diff options
Diffstat (limited to 'src/plugins')
25 files changed, 1202 insertions, 784 deletions
diff --git a/src/plugins/bearer/connman/connman.pro b/src/plugins/bearer/connman/connman.pro index bc4efe8b62..efa13a6ebd 100644 --- a/src/plugins/bearer/connman/connman.pro +++ b/src/plugins/bearer/connman/connman.pro @@ -8,14 +8,14 @@ QT = core network-private dbus CONFIG += link_pkgconfig HEADERS += qconnmanservice_linux_p.h \ - qofonoservice_linux_p.h \ + ../linux_common/qofonoservice_linux_p.h \ qconnmanengine.h \ ../qnetworksession_impl.h \ ../qbearerengine_impl.h SOURCES += main.cpp \ qconnmanservice_linux.cpp \ - qofonoservice_linux.cpp \ + ../linux_common/qofonoservice_linux.cpp \ qconnmanengine.cpp \ ../qnetworksession_impl.cpp diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h index 52e8b384a0..a995d8ed25 100644 --- a/src/plugins/bearer/connman/qconnmanengine.h +++ b/src/plugins/bearer/connman/qconnmanengine.h @@ -48,7 +48,7 @@ #include "../qbearerengine_impl.h" #include "qconnmanservice_linux_p.h" -#include "qofonoservice_linux_p.h" +#include "../linux_common/qofonoservice_linux_p.h" #include <QMap> #include <QVariant> diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp index 2ce2bd40e4..b2e2131a92 100644 --- a/src/plugins/bearer/connman/qofonoservice_linux.cpp +++ b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp @@ -95,14 +95,12 @@ QStringList QOfonoManagerInterface::getModems() { if (modemList.isEmpty()) { QList<QVariant> argumentList; - QDBusPendingReply<PathPropertiesList> reply = asyncCallWithArgumentList(QLatin1String("GetModems"), argumentList); + QDBusPendingReply<PathPropertiesList> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetModems"), argumentList); reply.waitForFinished(); if (!reply.isError()) { foreach (ObjectPathProperties modem, reply.value()) { modemList << modem.path.path(); } - } else { - qDebug() << reply.error().message(); } } @@ -114,7 +112,8 @@ QString QOfonoManagerInterface::currentModem() QStringList modems = getModems(); foreach (const QString &modem, modems) { QOfonoModemInterface device(modem); - if (device.isPowered() && device.isOnline()) + if (device.isPowered() && device.isOnline() + && device.interfaces().contains(QStringLiteral("org.ofono.NetworkRegistration"))) return modem; } return QString(); @@ -171,11 +170,17 @@ bool QOfonoModemInterface::isOnline() return qdbus_cast<bool>(var); } +QStringList QOfonoModemInterface::interfaces() +{ + const QVariant var = getProperty(QStringLiteral("Interfaces")); + return var.toStringList(); +} + QVariantMap QOfonoModemInterface::getProperties() { if (propertiesMap.isEmpty()) { QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); if (!reply.isError()) { propertiesMap = reply.value(); } @@ -187,7 +192,8 @@ QVariant QOfonoModemInterface::getProperty(const QString &property) { QVariant var; QVariantMap map = getProperties(); - var = map.value(property); + if (map.contains(property)) + var = map.value(property); return var; } @@ -214,7 +220,8 @@ QVariant QOfonoNetworkRegistrationInterface::getProperty(const QString &property { QVariant var; QVariantMap map = getProperties(); - var = map.value(property); + if (map.contains(property)) + var = map.value(property); return var; } @@ -222,12 +229,10 @@ QVariantMap QOfonoNetworkRegistrationInterface::getProperties() { if (propertiesMap.isEmpty()) { QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); reply.waitForFinished(); if (!reply.isError()) { propertiesMap = reply.value(); - } else { - qDebug() << reply.error().message(); } } return propertiesMap; @@ -270,11 +275,18 @@ bool QOfonoDataConnectionManagerInterface::roamingAllowed() return qdbus_cast<bool>(var); } +QString QOfonoDataConnectionManagerInterface::bearer() +{ + QVariant var = getProperty(QStringLiteral("Bearer")); + return qdbus_cast<QString>(var); +} + QVariant QOfonoDataConnectionManagerInterface::getProperty(const QString &property) { QVariant var; QVariantMap map = getProperties(); - var = map.value(property); + if (map.contains(property)) + var = map.value(property); return var; } @@ -282,7 +294,7 @@ QVariantMap QOfonoDataConnectionManagerInterface::getProperties() { if (propertiesMap.isEmpty()) { QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); if (!reply.isError()) { propertiesMap = reply.value(); } @@ -297,6 +309,68 @@ void QOfonoDataConnectionManagerInterface::propertyChanged(const QString &name, Q_EMIT roamingAllowedChanged(value.variant().toBool()); } + +QOfonoConnectionContextInterface::QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent) + : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE), + dbusPathName, + OFONO_CONNECTION_CONTEXT_INTERFACE, + QDBusConnection::systemBus(), parent) +{ + QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE), + path(), + QLatin1String(OFONO_MODEM_INTERFACE), + QLatin1String("PropertyChanged"), + this,SLOT(propertyChanged(QString,QDBusVariant))); +} + +QOfonoConnectionContextInterface::~QOfonoConnectionContextInterface() +{ +} + +QVariantMap QOfonoConnectionContextInterface::getProperties() +{ + if (propertiesMap.isEmpty()) { + QList<QVariant> argumentList; + QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); + if (!reply.isError()) { + propertiesMap = reply.value(); + } + } + return propertiesMap; +} + +void QOfonoConnectionContextInterface::propertyChanged(const QString &name, const QDBusVariant &value) +{ + propertiesMap[name] = value.variant(); +} + +QVariant QOfonoConnectionContextInterface::getProperty(const QString &property) +{ + QVariant var; + QVariantMap map = getProperties(); + if (map.contains(property)) + var = map.value(property); + return var; +} + +bool QOfonoConnectionContextInterface::active() +{ + QVariant var = getProperty(QStringLiteral("Active")); + return qdbus_cast<bool>(var); +} + +QString QOfonoConnectionContextInterface::accessPointName() +{ + QVariant var = getProperty(QStringLiteral("AccessPointName")); + return qdbus_cast<QString>(var); +} + +QString QOfonoConnectionContextInterface::name() +{ + QVariant var = getProperty(QStringLiteral("Name")); + return qdbus_cast<QString>(var); +} + QT_END_NAMESPACE #endif // QT_NO_DBUS diff --git a/src/plugins/bearer/connman/qofonoservice_linux_p.h b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h index 8a6a932e0d..0ed00d94ff 100644 --- a/src/plugins/bearer/connman/qofonoservice_linux_p.h +++ b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h @@ -67,6 +67,7 @@ #define OFONO_MODEM_INTERFACE "org.ofono.Modem" #define OFONO_NETWORK_REGISTRATION_INTERFACE "org.ofono.NetworkRegistration" #define OFONO_DATA_CONNECTION_MANAGER_INTERFACE "org.ofono.ConnectionManager" +#define OFONO_CONNECTION_CONTEXT_INTERFACE "org.ofono.ConnectionContext" QT_BEGIN_NAMESPACE @@ -114,6 +115,7 @@ public: bool isPowered(); bool isOnline(); + QStringList interfaces(); private: QVariantMap getProperties(); QVariantMap propertiesMap; @@ -152,17 +154,39 @@ public: QStringList contexts(); bool roamingAllowed(); + QVariant getProperty(const QString &); + QString bearer(); Q_SIGNALS: void roamingAllowedChanged(bool); private: QVariantMap getProperties(); QVariantMap propertiesMap; - QVariant getProperty(const QString &); QStringList contextList; private slots: void propertyChanged(const QString &, const QDBusVariant &value); }; +class QOfonoConnectionContextInterface : public QDBusAbstractInterface +{ + Q_OBJECT + +public: + + explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = 0); + ~QOfonoConnectionContextInterface(); + + QVariant getProperty(const QString &); + bool active(); + QString accessPointName(); + QString name(); + +Q_SIGNALS: +private: + QVariantMap getProperties(); + QVariantMap propertiesMap; +private slots: + void propertyChanged(const QString &, const QDBusVariant &value); +}; QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro index 1ed9bfaa1b..b3a270615c 100644 --- a/src/plugins/bearer/networkmanager/networkmanager.pro +++ b/src/plugins/bearer/networkmanager/networkmanager.pro @@ -6,16 +6,16 @@ load(qt_plugin) QT = core network-private dbus -HEADERS += qnmdbushelper.h \ - qnetworkmanagerservice.h \ +HEADERS += qnetworkmanagerservice.h \ qnetworkmanagerengine.h \ + ../linux_common/qofonoservice_linux_p.h \ ../qnetworksession_impl.h \ ../qbearerengine_impl.h SOURCES += main.cpp \ - qnmdbushelper.cpp \ qnetworkmanagerservice.cpp \ qnetworkmanagerengine.cpp \ + ../linux_common/qofonoservice_linux.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += networkmanager.json diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 5f49ea0b6d..a8244f05cf 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -47,6 +47,7 @@ #include <QDBusInterface> #include <QDBusMessage> #include <QDBusReply> +#include "../linux_common/qofonoservice_linux_p.h" #ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS @@ -57,45 +58,80 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) : QBearerEngineImpl(parent), managerInterface(new QNetworkManagerInterface(this)), systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)), - userSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)) + ofonoManager(new QOfonoManagerInterface(this)) { + if (!managerInterface->isValid()) return; - managerInterface->setConnections(); + qDBusRegisterMetaType<QNmSettingsMap>(); + connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)), this, SLOT(deviceAdded(QDBusObjectPath))); connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)), this, SLOT(deviceRemoved(QDBusObjectPath))); connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), this, SLOT(activationFinished(QDBusPendingCallWatcher*))); - connect(managerInterface, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)), - this, SLOT(interfacePropertiesChanged(QString,QMap<QString,QVariant>))); - - qDBusRegisterMetaType<QNmSettingsMap>(); + connect(managerInterface, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), + this, SLOT(interfacePropertiesChanged(QMap<QString,QVariant>))); + managerInterface->setConnections(); - systemSettings->setConnections(); connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)), this, SLOT(newConnection(QDBusObjectPath))); - - userSettings->setConnections(); - connect(userSettings, SIGNAL(newConnection(QDBusObjectPath)), - this, SLOT(newConnection(QDBusObjectPath))); + systemSettings->setConnections(); } QNetworkManagerEngine::~QNetworkManagerEngine() { qDeleteAll(connections); + connections.clear(); qDeleteAll(accessPoints); + accessPoints.clear(); qDeleteAll(wirelessDevices); - qDeleteAll(activeConnections); + wirelessDevices.clear(); + qDeleteAll(activeConnectionsList); + activeConnectionsList.clear(); + qDeleteAll(interfaceDevices); + interfaceDevices.clear(); + + connectionInterfaces.clear(); + + qDeleteAll(ofonoContextManagers); + ofonoContextManagers.clear(); + + qDeleteAll(wiredDevices); + wiredDevices.clear(); } void QNetworkManagerEngine::initialize() { QMutexLocker locker(&mutex); - // Get current list of access points. + if (ofonoManager->isValid()) { + Q_FOREACH (const QString &modem, ofonoManager->getModems()) { + QOfonoDataConnectionManagerInterface *ofonoContextManager + = new QOfonoDataConnectionManagerInterface(modem,this); + ofonoContextManagers.insert(modem, ofonoContextManager); + } + } + // Get active connections. + foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { + + QNetworkManagerConnectionActive *activeConnection = + new QNetworkManagerConnectionActive(acPath.path(),this); + activeConnectionsList.insert(acPath.path(), activeConnection); + connect(activeConnection, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), + this, SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>))); + activeConnection->setConnections(); + + QStringList devices = activeConnection->devices(); + if (!devices.isEmpty()) { + QNetworkManagerInterfaceDevice device(devices.at(0),this); + connectionInterfaces.insert(activeConnection->connection().path(),device.networkInterface()); + } + } + + // Get current list of access points. foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { locker.unlock(); deviceAdded(devicePath); //add all accesspoints @@ -103,7 +139,6 @@ void QNetworkManagerEngine::initialize() } // Get connections. - foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) { locker.unlock(); if (!hasIdentifier(settingsPath.path())) @@ -111,57 +146,19 @@ void QNetworkManagerEngine::initialize() locker.relock(); } - foreach (const QDBusObjectPath &settingsPath, userSettings->listConnections()) { - locker.unlock(); - if (!hasIdentifier(settingsPath.path())) - newConnection(settingsPath, userSettings); - locker.relock(); - } - - // Get active connections. - foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { - QNetworkManagerConnectionActive *activeConnection = - new QNetworkManagerConnectionActive(acPath.path(),this); - activeConnections.insert(acPath.path(), activeConnection); - - activeConnection->setConnections(); - connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)), - this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>))); - } Q_EMIT updateCompleted(); } bool QNetworkManagerEngine::networkManagerAvailable() const { - QMutexLocker locker(&mutex); - return managerInterface->isValid(); } -QString QNetworkManagerEngine::getInterfaceFromId(const QString &id) +QString QNetworkManagerEngine::getInterfaceFromId(const QString &settingsPath) { - QMutexLocker locker(&mutex); - - foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { - QNetworkManagerConnectionActive activeConnection(acPath.path()); - - const QString identifier = activeConnection.connection().path(); - - if (id == identifier) { - QList<QDBusObjectPath> devices = activeConnection.devices(); - - if (devices.isEmpty()) - continue; - - QNetworkManagerInterfaceDevice device(devices.at(0).path()); - return device.networkInterface(); - } - } - - return QString(); + return connectionInterfaces.value(settingsPath); } - bool QNetworkManagerEngine::hasIdentifier(const QString &id) { QMutexLocker locker(&mutex); @@ -177,35 +174,34 @@ void QNetworkManagerEngine::connectToId(const QString &id) if (!connection) return; - QNmSettingsMap map = connection->getSettings(); - const QString connectionType = map.value("connection").value("type").toString(); + NMDeviceType connectionType = connection->getType(); QString dbusDevicePath; - foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { - QNetworkManagerInterfaceDevice device(devicePath.path()); - if (device.deviceType() == DEVICE_TYPE_ETHERNET && - connectionType == QLatin1String("802-3-ethernet")) { - dbusDevicePath = devicePath.path(); + const QString settingsPath = connection->connectionInterface()->path(); + QString specificPath = configuredAccessPoints.key(settingsPath); + + QHashIterator<QString, QNetworkManagerInterfaceDevice*> i(interfaceDevices); + while (i.hasNext()) { + i.next(); + if (i.value()->deviceType() == DEVICE_TYPE_ETHERNET && + connectionType == DEVICE_TYPE_ETHERNET) { + dbusDevicePath = i.key(); break; - } else if (device.deviceType() == DEVICE_TYPE_WIFI && - connectionType == QLatin1String("802-11-wireless")) { - dbusDevicePath = devicePath.path(); + } else if (i.value()->deviceType() == DEVICE_TYPE_WIFI && + connectionType == DEVICE_TYPE_WIFI) { + dbusDevicePath = i.key(); break; - } else if (device.deviceType() == DEVICE_TYPE_MODEM && - connectionType == QLatin1String("gsm")) { - dbusDevicePath = devicePath.path(); + } else if (i.value()->deviceType() == DEVICE_TYPE_MODEM && + connectionType == DEVICE_TYPE_MODEM) { + dbusDevicePath = i.key(); break; } } - const QString service = connection->connectionInterface()->service(); - const QString settingsPath = connection->connectionInterface()->path(); - QString specificPath = configuredAccessPoints.key(settingsPath); - if (specificPath.isEmpty()) specificPath = "/"; - managerInterface->activateConnection(service, QDBusObjectPath(settingsPath), + managerInterface->activateConnection(QDBusObjectPath(settingsPath), QDBusObjectPath(dbusDevicePath), QDBusObjectPath(specificPath)); } @@ -221,13 +217,11 @@ void QNetworkManagerEngine::disconnectFromId(const QString &id) return; } - foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { - QNetworkManagerConnectionActive activeConnection(acPath.path()); - - const QString identifier = activeConnection.connection().path(); - - if (id == identifier && accessPointConfigurations.contains(id)) { - managerInterface->deactivateConnection(acPath); + QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList); + while (i.hasNext()) { + i.next(); + if (id == i.value()->connection().path() && accessPointConfigurations.contains(id)) { + managerInterface->deactivateConnection(QDBusObjectPath(i.key())); break; } } @@ -250,12 +244,9 @@ void QNetworkManagerEngine::scanFinished() QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection); } -void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, - const QMap<QString, QVariant> &properties) +void QNetworkManagerEngine::interfacePropertiesChanged(const QMap<QString, QVariant> &properties) { - Q_UNUSED(path) QMutexLocker locker(&mutex); - QMapIterator<QString, QVariant> i(properties); while (i.hasNext()) { i.next(); @@ -267,22 +258,20 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, qdbus_cast<QList<QDBusObjectPath> >(i.value().value<QDBusArgument>()); QStringList identifiers = accessPointConfigurations.keys(); - foreach (const QString &id, identifiers) - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - QStringList priorActiveConnections = this->activeConnections.keys(); + QStringList priorActiveConnections = activeConnectionsList.keys(); foreach (const QDBusObjectPath &acPath, activeConnections) { priorActiveConnections.removeOne(acPath.path()); QNetworkManagerConnectionActive *activeConnection = - this->activeConnections.value(acPath.path()); + activeConnectionsList.value(acPath.path()); + if (!activeConnection) { activeConnection = new QNetworkManagerConnectionActive(acPath.path(),this); - this->activeConnections.insert(acPath.path(), activeConnection); + activeConnectionsList.insert(acPath.path(), activeConnection); + connect(activeConnection, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), + this, SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>))); activeConnection->setConnections(); - connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)), - this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>))); } const QString id = activeConnection->connection().path(); @@ -295,6 +284,11 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && ptr->state != QNetworkConfiguration::Active) { ptr->state = QNetworkConfiguration::Active; + + if (activeConnectionsList.value(id) && activeConnectionsList.value(id)->defaultRoute() + && managerInterface->state() < QNetworkManagerInterface::NM_STATE_CONNECTED_GLOBAL) { + ptr->purpose = QNetworkConfiguration::PrivatePurpose; + } ptr->mutex.unlock(); locker.unlock(); @@ -307,7 +301,7 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, } while (!priorActiveConnections.isEmpty()) - delete this->activeConnections.take(priorActiveConnections.takeFirst()); + delete activeConnectionsList.take(priorActiveConnections.takeFirst()); while (!identifiers.isEmpty()) { QNetworkConfigurationPrivatePointer ptr = @@ -330,14 +324,13 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, } } -void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &path, - const QMap<QString, QVariant> &properties) +void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QMap<QString, QVariant> &properties) { QMutexLocker locker(&mutex); Q_UNUSED(properties) - QNetworkManagerConnectionActive *activeConnection = activeConnections.value(path); + QNetworkManagerConnectionActive *activeConnection = qobject_cast<QNetworkManagerConnectionActive *>(sender()); if (!activeConnection) return; @@ -347,8 +340,13 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { ptr->mutex.lock(); - if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && - ptr->state != QNetworkConfiguration::Active) { + if (properties.value("State").toUInt() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + QStringList devices = activeConnection->devices(); + if (!devices.isEmpty()) { + QNetworkManagerInterfaceDevice device(devices.at(0),this); + connectionInterfaces.insert(id,device.networkInterface()); + } + ptr->state |= QNetworkConfiguration::Active; ptr->mutex.unlock(); @@ -356,22 +354,17 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat emit configurationChanged(ptr); locker.relock(); } else { + connectionInterfaces.remove(id); ptr->mutex.unlock(); } } } -void QNetworkManagerEngine::devicePropertiesChanged(const QString &/*path*/,quint32 /*state*/) -{ -// Q_UNUSED(path); -// Q_UNUSED(state) -} - -void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &activeConnectionsList) +void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &connectionsList) { QMutexLocker locker(&mutex); for (int i = 0; i < connections.count(); ++i) { - if (activeConnectionsList.contains(connections.at(i)->connectionInterface()->path())) + if (connectionsList.contains(connections.at(i)->connectionInterface()->path())) continue; const QString settingsPath = connections.at(i)->connectionInterface()->path(); @@ -392,33 +385,36 @@ void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &activeCo void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path) { - QMutexLocker locker(&mutex); QNetworkManagerInterfaceDevice *iDevice; iDevice = new QNetworkManagerInterfaceDevice(path.path(),this); connect(iDevice,SIGNAL(connectionsChanged(QStringList)), this,SLOT(deviceConnectionsChanged(QStringList))); - connect(iDevice,SIGNAL(stateChanged(QString,quint32)), - this,SLOT(devicePropertiesChanged(QString,quint32))); iDevice->setConnections(); interfaceDevices.insert(path.path(),iDevice); - if (iDevice->deviceType() == DEVICE_TYPE_WIFI) { QNetworkManagerInterfaceDeviceWireless *wirelessDevice = new QNetworkManagerInterfaceDeviceWireless(iDevice->connectionInterface()->path(),this); - wirelessDevice->setConnections(); connect(wirelessDevice, SIGNAL(accessPointAdded(QString)), this, SLOT(newAccessPoint(QString))); connect(wirelessDevice, SIGNAL(accessPointRemoved(QString)), this, SLOT(removeAccessPoint(QString))); connect(wirelessDevice,SIGNAL(scanDone()),this,SLOT(scanFinished())); + wirelessDevice->setConnections(); foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) newAccessPoint(apPath.path()); wirelessDevices.insert(path.path(), wirelessDevice); } + + if (iDevice->deviceType() == DEVICE_TYPE_ETHERNET) { + QNetworkManagerInterfaceDeviceWired *wiredDevice = + new QNetworkManagerInterfaceDeviceWired(iDevice->connectionInterface()->path(),this); + connect(wiredDevice,SIGNAL(carrierChanged(bool)),this,SLOT(wiredCarrierChanged(bool))); + wiredDevices.insert(iDevice->connectionInterface()->path(), wiredDevice); + } } void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path) @@ -435,6 +431,41 @@ void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path) delete wirelessDevices.take(path.path()); locker.relock(); } + if (wiredDevices.contains(path.path())) { + locker.unlock(); + delete wiredDevices.take(path.path()); + locker.relock(); + } +} + +void QNetworkManagerEngine::wiredCarrierChanged(bool carrier) +{ + QNetworkManagerInterfaceDeviceWired *deviceWired = qobject_cast<QNetworkManagerInterfaceDeviceWired *>(sender()); + if (!deviceWired) + return; + QMutexLocker locker(&mutex); + foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) { + for (int i = 0; i < connections.count(); ++i) { + QNetworkManagerSettingsConnection *connection = connections.at(i); + if (connection->getType() == DEVICE_TYPE_ETHERNET + && settingsPath.path() == connection->connectionInterface()->path()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.value(settingsPath.path()); + + if (ptr) { + ptr->mutex.lock(); + if (carrier) + ptr->state |= QNetworkConfiguration::Discovered; + else + ptr->state = QNetworkConfiguration::Defined; + ptr->mutex.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + return; + } + } + } + } } void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, @@ -444,57 +475,72 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, if (!settings) settings = qobject_cast<QNetworkManagerSettings *>(sender()); - if (!settings) + if (!settings) { return; + } - settings->deleteLater(); QNetworkManagerSettingsConnection *connection = new QNetworkManagerSettingsConnection(settings->connectionInterface()->service(), path.path(),this); - QString apPath; - for (int i = 0; i < accessPoints.count(); ++i) { - if (connection->getSsid() == accessPoints.at(i)->ssid()) { - // remove the corresponding accesspoint from configurations - apPath = accessPoints.at(i)->connectionInterface()->path(); - - QNetworkConfigurationPrivatePointer ptr - = accessPointConfigurations.take(apPath); - if (ptr) { - locker.unlock(); - emit configurationRemoved(ptr); - locker.relock(); - } - } + const QString settingsPath = connection->connectionInterface()->path(); + if (accessPointConfigurations.contains(settingsPath)) { + return; } + connections.append(connection); connect(connection,SIGNAL(removed(QString)),this,SLOT(removeConnection(QString))); connect(connection,SIGNAL(updated()),this,SLOT(updateConnection())); connection->setConnections(); - const QString settingsPath = connection->connectionInterface()->path(); + NMDeviceType deviceType = connection->getType(); - if (connection->getType() == DEVICE_TYPE_WIFI - && !configuredAccessPoints.contains(settingsPath)) - configuredAccessPoints.insert(apPath,settingsPath); + if (deviceType == DEVICE_TYPE_WIFI) { + QString apPath; + for (int i = 0; i < accessPoints.count(); ++i) { + if (connection->getSsid() == accessPoints.at(i)->ssid()) { + // remove the corresponding accesspoint from configurations + apPath = accessPoints.at(i)->connectionInterface()->path(); + QNetworkConfigurationPrivatePointer ptr + = accessPointConfigurations.take(apPath); + if (ptr) { + locker.unlock(); + emit configurationRemoved(ptr); + locker.relock(); + } + } + } + if (!configuredAccessPoints.contains(settingsPath)) + configuredAccessPoints.insert(apPath,settingsPath); + } QNetworkConfigurationPrivate *cpPriv = parseConnection(settingsPath, connection->getSettings()); // Check if connection is active. - foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { - QNetworkManagerConnectionActive activeConnection(acPath.path()); - - if (activeConnection.defaultRoute() && - activeConnection.connection().path() == settingsPath && - activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList); + while (i.hasNext()) { + i.next(); + if (i.value()->connection().path() == settingsPath) { cpPriv->state |= QNetworkConfiguration::Active; break; } } + if (deviceType == DEVICE_TYPE_ETHERNET) { + QHashIterator<QString, QNetworkManagerInterfaceDevice*> i(interfaceDevices); + while (i.hasNext()) { + i.next(); + if (i.value()->deviceType() == deviceType) { + QNetworkManagerInterfaceDeviceWired *wiredDevice + = wiredDevices.value(i.value()->connectionInterface()->path()); + if (wiredDevice->carrier()) { + cpPriv->state |= QNetworkConfiguration::Discovered; + } + } + } + } QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); - locker.unlock(); emit configurationAdded(ptr); } @@ -505,6 +551,7 @@ void QNetworkManagerEngine::removeConnection(const QString &path) QNetworkManagerSettingsConnection *connection = qobject_cast<QNetworkManagerSettingsConnection *>(sender()); + if (!connection) return; @@ -525,6 +572,7 @@ void QNetworkManagerEngine::removeConnection(const QString &path) while (i.hasNext()) { i.next(); if (i.value() == path) { + configuredAccessPoints.remove(i.key()); newAccessPoint(i.key()); } } @@ -538,8 +586,6 @@ void QNetworkManagerEngine::updateConnection() qobject_cast<QNetworkManagerSettingsConnection *>(sender()); if (!connection) return; - - connection->deleteLater(); const QString settingsPath = connection->connectionInterface()->path(); QNetworkConfigurationPrivate *cpPriv = parseConnection(settingsPath, connection->getSettings()); @@ -575,10 +621,9 @@ void QNetworkManagerEngine::updateConnection() void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) { QMutexLocker locker(&mutex); - + QDBusPendingReply<QDBusObjectPath> reply(*watcher); watcher->deleteLater(); - QDBusPendingReply<QDBusObjectPath> reply(*watcher); if (!reply.isError()) { QDBusObjectPath result = reply.value(); @@ -620,15 +665,14 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path) if (okToAdd) { accessPoints.append(accessPoint); accessPoint->setConnections(); - connect(accessPoint, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), - this, SLOT(updateAccessPoint(QMap<QString,QVariant>))); } - // Check if configuration exists for connection. if (!accessPoint->ssid().isEmpty()) { + for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); const QString settingsPath = connection->connectionInterface()->path(); + if (accessPoint->ssid() == connection->getSsid()) { if (!configuredAccessPoints.contains(path)) { configuredAccessPoints.insert(path,settingsPath); @@ -655,11 +699,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path) ptr->isValid = true; ptr->id = path; ptr->type = QNetworkConfiguration::InternetAccessPoint; - if (accessPoint->flags() == NM_802_11_AP_FLAGS_PRIVACY) { - ptr->purpose = QNetworkConfiguration::PrivatePurpose; - } else { - ptr->purpose = QNetworkConfiguration::PublicPurpose; - } + ptr->purpose = QNetworkConfiguration::PublicPurpose; ptr->state = QNetworkConfiguration::Undefined; ptr->bearerType = QNetworkConfiguration::BearerWLAN; @@ -674,13 +714,13 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path) QMutexLocker locker(&mutex); for (int i = 0; i < accessPoints.count(); ++i) { QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i); - if (accessPoint->connectionInterface()->path() == path) { accessPoints.removeOne(accessPoint); if (configuredAccessPoints.contains(accessPoint->connectionInterface()->path())) { // find connection and change state to Defined configuredAccessPoints.remove(accessPoint->connectionInterface()->path()); + for (int i = 0; i < connections.count(); ++i) { QNetworkManagerSettingsConnection *connection = connections.at(i); @@ -706,8 +746,6 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path) if (ptr) { locker.unlock(); - - locker.unlock(); emit configurationRemoved(ptr); locker.relock(); } @@ -718,42 +756,9 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path) } } -void QNetworkManagerEngine::updateAccessPoint(const QMap<QString, QVariant> &map) -{ - QMutexLocker locker(&mutex); - - Q_UNUSED(map) - - QNetworkManagerInterfaceAccessPoint *accessPoint = - qobject_cast<QNetworkManagerInterfaceAccessPoint *>(sender()); - if (!accessPoint) - return; - accessPoint->deleteLater(); - for (int i = 0; i < connections.count(); ++i) { - QNetworkManagerSettingsConnection *connection = connections.at(i); - - if (accessPoint->ssid() == connection->getSsid()) { - const QString settingsPath = connection->connectionInterface()->path(); - const QString connectionId = settingsPath; - - QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.value(connectionId); - ptr->mutex.lock(); - QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; - ptr->state = (flag | QNetworkConfiguration::Discovered); - ptr->mutex.unlock(); - - locker.unlock(); - emit configurationChanged(ptr); - return; - } - } -} - QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &settingsPath, const QNmSettingsMap &map) { - // Q_UNUSED(service); QMutexLocker locker(&mutex); QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate; cpPriv->name = map.value("connection").value("id").toString(); @@ -765,18 +770,16 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri cpPriv->purpose = QNetworkConfiguration::PublicPurpose; cpPriv->state = QNetworkConfiguration::Defined; - const QString connectionType = map.value("connection").value("type").toString(); if (connectionType == QLatin1String("802-3-ethernet")) { cpPriv->bearerType = QNetworkConfiguration::BearerEthernet; - cpPriv->purpose = QNetworkConfiguration::PublicPurpose; foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { - QNetworkManagerInterfaceDevice device(devicePath.path()); + QNetworkManagerInterfaceDevice device(devicePath.path(),this); if (device.deviceType() == DEVICE_TYPE_ETHERNET) { - QNetworkManagerInterfaceDeviceWired wiredDevice(device.connectionInterface()->path()); - if (wiredDevice.carrier()) { + QNetworkManagerInterfaceDeviceWired *wiredDevice = wiredDevices.value(device.connectionInterface()->path()); + if (wiredDevice->carrier()) { cpPriv->state |= QNetworkConfiguration::Discovered; break; } @@ -786,12 +789,6 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri cpPriv->bearerType = QNetworkConfiguration::BearerWLAN; const QString connectionSsid = map.value("802-11-wireless").value("ssid").toString(); - const QString connectionSecurity = map.value("802-11-wireless").value("security").toString(); - if (!connectionSecurity.isEmpty()) { - cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; - } else { - cpPriv->purpose = QNetworkConfiguration::PublicPurpose; - } for (int i = 0; i < accessPoints.count(); ++i) { if (connectionSsid == accessPoints.at(i)->ssid() && map.value("802-11-wireless").value("seen-bssids").toStringList().contains(accessPoints.at(i)->hwAddress())) { @@ -814,30 +811,13 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri } } else if (connectionType == QLatin1String("gsm")) { - foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { - QNetworkManagerInterfaceDevice device(devicePath.path()); + const QString contextPath = map.value("connection").value("id").toString(); + cpPriv->name = contextName(contextPath); + cpPriv->bearerType = currentBearerType(contextPath); - if (device.deviceType() == DEVICE_TYPE_MODEM) { - QNetworkManagerInterfaceDeviceModem deviceModem(device.connectionInterface()->path(),this); - switch (deviceModem.currentCapabilities()) { - case 2: - cpPriv->bearerType = QNetworkConfiguration::Bearer2G; - break; - case 4: - cpPriv->bearerType = QNetworkConfiguration::Bearer3G; - break; - case 8: - cpPriv->bearerType = QNetworkConfiguration::Bearer4G; - break; - default: - cpPriv->bearerType = QNetworkConfiguration::BearerUnknown; - break; - }; - } + if (map.value("connection").contains("timestamp")) { + cpPriv->state |= QNetworkConfiguration::Discovered; } - - cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; - cpPriv->state |= QNetworkConfiguration::Discovered; } return cpPriv; @@ -857,7 +837,6 @@ QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &id) { QMutexLocker locker(&mutex); - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (!ptr) @@ -866,8 +845,8 @@ QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &i if (!ptr->isValid) return QNetworkSession::Invalid; - foreach (const QString &acPath, activeConnections.keys()) { - QNetworkManagerConnectionActive *activeConnection = activeConnections.value(acPath); + foreach (const QString &acPath, activeConnectionsList.keys()) { + QNetworkManagerConnectionActive *activeConnection = activeConnectionsList.value(acPath); const QString identifier = activeConnection->connection().path(); @@ -899,7 +878,7 @@ quint64 QNetworkManagerEngine::bytesWritten(const QString &id) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { - const QString networkInterface = getInterfaceFromId(id); + const QString networkInterface = connectionInterfaces.value(id); if (!networkInterface.isEmpty()) { const QString devFile = QLatin1String("/sys/class/net/") + networkInterface + @@ -927,7 +906,7 @@ quint64 QNetworkManagerEngine::bytesReceived(const QString &id) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { - const QString networkInterface = getInterfaceFromId(id); + const QString networkInterface = connectionInterfaces.value(id); if (!networkInterface.isEmpty()) { const QString devFile = QLatin1String("/sys/class/net/") + networkInterface + @@ -974,9 +953,67 @@ QNetworkSessionPrivate *QNetworkManagerEngine::createSessionBackend() QNetworkConfigurationPrivatePointer QNetworkManagerEngine::defaultConfiguration() { + QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList); + while (i.hasNext()) { + i.next(); + QNetworkManagerConnectionActive *activeConnection = i.value(); + if ((activeConnection->defaultRoute() || activeConnection->default6Route())) { + return accessPointConfigurations.value(activeConnection->connection().path()); + } + } + return QNetworkConfigurationPrivatePointer(); } +QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const QString &id) +{ + if (ofonoManager->isValid()) { + QString contextPart = id.section('/', -1); + + QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); + while (i.hasNext()) { + i.next(); + QString contextPath = i.key() +"/"+contextPart; + if (i.value()->contexts().contains(contextPath)) { + + QString bearer = i.value()->bearer(); + if (bearer == QStringLiteral("gsm")) { + return QNetworkConfiguration::Bearer2G; + } else if (bearer == QStringLiteral("edge")) { + return QNetworkConfiguration::Bearer2G; + } else if (bearer == QStringLiteral("umts")) { + return QNetworkConfiguration::BearerWCDMA; + } else if (bearer == QStringLiteral("hspa") + || bearer == QStringLiteral("hsdpa") + || bearer == QStringLiteral("hsupa")) { + return QNetworkConfiguration::BearerHSPA; + } else if (bearer == QStringLiteral("lte")) { + return QNetworkConfiguration::BearerLTE; + } + } + } + } + return QNetworkConfiguration::BearerUnknown; +} + +QString QNetworkManagerEngine::contextName(const QString &path) +{ + if (ofonoManager->isValid()) { + QString contextPart = path.section('/', -1); + QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); + while (i.hasNext()) { + i.next(); + Q_FOREACH (const QString &oContext, i.value()->contexts()) { + if (oContext.contains(contextPart)) { + QOfonoConnectionContextInterface contextInterface(oContext,this); + return contextInterface.name(); + } + } + } + } + return path; +} + QT_END_NAMESPACE #endif // QT_NO_DBUS diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index ab1cfea71e..671ed80dab 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -49,6 +49,8 @@ #include "qnetworkmanagerservice.h" +#include "../linux_common/qofonoservice_linux_p.h" + #include <QMap> #include <QVariant> @@ -89,11 +91,8 @@ public: QNetworkConfigurationPrivatePointer defaultConfiguration(); private Q_SLOTS: - void interfacePropertiesChanged(const QString &path, - const QMap<QString, QVariant> &properties); - void activeConnectionPropertiesChanged(const QString &path, - const QMap<QString, QVariant> &properties); - void devicePropertiesChanged(const QString &path, quint32); + void interfacePropertiesChanged(const QMap<QString, QVariant> &properties); + void activeConnectionPropertiesChanged(const QMap<QString, QVariant> &properties); void deviceAdded(const QDBusObjectPath &path); void deviceRemoved(const QDBusObjectPath &path); @@ -106,9 +105,10 @@ private Q_SLOTS: void newAccessPoint(const QString &path); void removeAccessPoint(const QString &path); - void updateAccessPoint(const QMap<QString, QVariant> &map); void scanFinished(); + void wiredCarrierChanged(bool); + private: QNetworkConfigurationPrivate *parseConnection(const QString &settingsPath, const QNmSettingsMap &map); @@ -116,14 +116,22 @@ private: QNetworkManagerInterface *managerInterface; QNetworkManagerSettings *systemSettings; - QNetworkManagerSettings *userSettings; + QHash<QString, QNetworkManagerInterfaceDeviceWired *> wiredDevices; QHash<QString, QNetworkManagerInterfaceDeviceWireless *> wirelessDevices; - QHash<QString, QNetworkManagerConnectionActive *> activeConnections; + + QHash<QString, QNetworkManagerConnectionActive *> activeConnectionsList; QList<QNetworkManagerSettingsConnection *> connections; QList<QNetworkManagerInterfaceAccessPoint *> accessPoints; QHash<QString, QNetworkManagerInterfaceDevice *> interfaceDevices; QMap<QString,QString> configuredAccessPoints; //ap, settings path + QHash<QString,QString> connectionInterfaces; // ac, interface + + QOfonoManagerInterface *ofonoManager; + QHash <QString, QOfonoDataConnectionManagerInterface *> ofonoContextManagers; + QNetworkConfiguration::BearerType currentBearerType(const QString &id); + QString contextName(const QString &path); + }; QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index f249ac6100..dc3b71ec8e 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -44,7 +44,6 @@ #include <QtDBus/QDBusPendingCall> #include "qnetworkmanagerservice.h" -#include "qnmdbushelper.h" #ifndef QT_NO_DBUS @@ -64,18 +63,38 @@ QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent) d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), - QDBusConnection::systemBus()); + QDBusConnection::systemBus(),parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; } d->valid = true; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)), - this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>))); - connect(nmDBusHelper,SIGNAL(pathForStateChanged(QString,quint32)), - this, SIGNAL(stateChanged(QString,quint32))); + QDBusInterface managerPropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + QLatin1String(NM_DBUS_PATH), + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus()); + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE); + QDBusPendingReply<QVariantMap> propsReply + = managerPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } + + QDBusPendingReply<QList <QDBusObjectPath> > nmReply + = d->connectionInterface->call(QLatin1String("GetDevices")); + nmReply.waitForFinished(); + if (!nmReply.isError()) { + devicesPathList = nmReply.value(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + QLatin1String(NM_DBUS_PATH), + QLatin1String(NM_DBUS_INTERFACE), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); } QNetworkManagerInterface::~QNetworkManagerInterface() @@ -91,27 +110,24 @@ bool QNetworkManagerInterface::isValid() bool QNetworkManagerInterface::setConnections() { - if(!isValid() ) + if (!isValid()) return false; - QDBusConnection dbusConnection = QDBusConnection::systemBus(); - - bool allOk = false; - if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>)))) { - allOk = true; - } - if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); + + bool allOk = false; + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), QLatin1String("DeviceAdded"), this,SIGNAL(deviceAdded(QDBusObjectPath)))) { allOk = true; } - if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), QLatin1String("DeviceRemoved"), @@ -127,14 +143,17 @@ QDBusInterface *QNetworkManagerInterface::connectionInterface() const return d->connectionInterface; } -QList <QDBusObjectPath> QNetworkManagerInterface::getDevices() const +QList <QDBusObjectPath> QNetworkManagerInterface::getDevices() { - QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("GetDevices")); - return reply.value(); + if (devicesPathList.isEmpty()) { + qWarning() << "using blocking call!"; + QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("GetDevices")); + devicesPathList = reply.value(); + } + return devicesPathList; } -void QNetworkManagerInterface::activateConnection( const QString &, - QDBusObjectPath connectionPath, +void QNetworkManagerInterface::activateConnection(QDBusObjectPath connectionPath, QDBusObjectPath devicePath, QDBusObjectPath specificObject) { @@ -150,28 +169,80 @@ void QNetworkManagerInterface::activateConnection( const QString &, void QNetworkManagerInterface::deactivateConnection(QDBusObjectPath connectionPath) const { - d->connectionInterface->call(QLatin1String("DeactivateConnection"), QVariant::fromValue(connectionPath)); + d->connectionInterface->asyncCall(QLatin1String("DeactivateConnection"), QVariant::fromValue(connectionPath)); } bool QNetworkManagerInterface::wirelessEnabled() const { - return d->connectionInterface->property("WirelessEnabled").toBool(); + if (propertyMap.contains("WirelessEnabled")) + return propertyMap.value("WirelessEnabled").toBool(); + return false; } bool QNetworkManagerInterface::wirelessHardwareEnabled() const { - return d->connectionInterface->property("WirelessHardwareEnabled").toBool(); + if (propertyMap.contains("WirelessHardwareEnabled")) + return propertyMap.value("WirelessHardwareEnabled").toBool(); + return false; } QList <QDBusObjectPath> QNetworkManagerInterface::activeConnections() const { - QVariant prop = d->connectionInterface->property("ActiveConnections"); - return prop.value<QList<QDBusObjectPath> >(); + if (propertyMap.contains("ActiveConnections")) { + + const QDBusArgument &dbusArgs = propertyMap.value("ActiveConnections").value<QDBusArgument>(); + QDBusObjectPath path; + QList <QDBusObjectPath> list; + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> path; + list.append(path); + } + dbusArgs.endArray(); + + return list; + } + + QList <QDBusObjectPath> list; + list << QDBusObjectPath(); + return list; +} + +QNetworkManagerInterface::NMState QNetworkManagerInterface::state() +{ + if (propertyMap.contains("State")) + return static_cast<QNetworkManagerInterface::NMState>(propertyMap.value("State").toUInt()); + return QNetworkManagerInterface::NM_STATE_UNKNOWN; +} + +QString QNetworkManagerInterface::version() const +{ + if (propertyMap.contains("Version")) + return propertyMap.value("Version").toString(); + return QString(); } -quint32 QNetworkManagerInterface::state() +void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map) { - return d->connectionInterface->property("State").toUInt(); + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + propertyMap.insert(i.key(),i.value()); + + if (i.key() == QStringLiteral("State")) { + quint32 state = i.value().toUInt(); + if (state == NM_DEVICE_STATE_ACTIVATED + || state == NM_DEVICE_STATE_DISCONNECTED + || state == NM_DEVICE_STATE_UNAVAILABLE + || state == NM_DEVICE_STATE_FAILED) { + Q_EMIT propertiesChanged(map); + Q_EMIT stateChanged(state); + } + } else if (i.key() == QStringLiteral("ActiveConnections")) { + Q_EMIT propertiesChanged(map); + } + } } class QNetworkManagerInterfaceAccessPointPrivate @@ -183,18 +254,38 @@ public: }; QNetworkManagerInterfaceAccessPoint::QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { d = new QNetworkManagerInterfaceAccessPointPrivate(); d->path = dbusPathName; d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), - QDBusConnection::systemBus()); + QDBusConnection::systemBus(),parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; } + QDBusInterface accessPointPropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus()); + + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT); + QDBusPendingReply<QVariantMap> propsReply + = accessPointPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); + d->valid = true; } @@ -212,24 +303,10 @@ bool QNetworkManagerInterfaceAccessPoint::isValid() bool QNetworkManagerInterfaceAccessPoint::setConnections() { - if(!isValid() ) + if (!isValid()) return false; - bool allOk = false; - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)), - this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>))); - - if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), - QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>))) ) { - allOk = true; - - } - return allOk; + return true; } QDBusInterface *QNetworkManagerInterfaceAccessPoint::connectionInterface() const @@ -239,47 +316,74 @@ QDBusInterface *QNetworkManagerInterfaceAccessPoint::connectionInterface() const quint32 QNetworkManagerInterfaceAccessPoint::flags() const { - return d->connectionInterface->property("Flags").toUInt(); + if (propertyMap.contains("Flags")) + return propertyMap.value("Flags").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceAccessPoint::wpaFlags() const { - return d->connectionInterface->property("WpaFlags").toUInt(); + if (propertyMap.contains("WpaFlags")) + return propertyMap.value("WpaFlags").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceAccessPoint::rsnFlags() const { - return d->connectionInterface->property("RsnFlags").toUInt(); + if (propertyMap.contains("RsnFlags")) + return propertyMap.value("RsnFlags").toUInt(); + return 0; } QString QNetworkManagerInterfaceAccessPoint::ssid() const { - return d->connectionInterface->property("Ssid").toString(); + if (propertyMap.contains("Ssid")) + return propertyMap.value("Ssid").toString(); + return QString(); } quint32 QNetworkManagerInterfaceAccessPoint::frequency() const { - return d->connectionInterface->property("Frequency").toUInt(); + if (propertyMap.contains("Frequency")) + return propertyMap.value("Frequency").toUInt(); + return 0; } QString QNetworkManagerInterfaceAccessPoint::hwAddress() const { - return d->connectionInterface->property("HwAddress").toString(); + if (propertyMap.contains("HwAddress")) + return propertyMap.value("HwAddress").toString(); + return QString(); } quint32 QNetworkManagerInterfaceAccessPoint::mode() const { - return d->connectionInterface->property("Mode").toUInt(); + if (propertyMap.contains("Mode")) + return propertyMap.value("Mode").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceAccessPoint::maxBitrate() const { - return d->connectionInterface->property("MaxBitrate").toUInt(); + if (propertyMap.contains("MaxBitrate")) + return propertyMap.value("MaxBitrate").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceAccessPoint::strength() const { - return d->connectionInterface->property("Strength").toUInt(); + if (propertyMap.contains("Strength")) + return propertyMap.value("Strength").toUInt(); + return 0; +} + +void QNetworkManagerInterfaceAccessPoint::propertiesSwap(QMap<QString,QVariant> map) +{ + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + propertyMap.insert(i.key(),i.value()); + } } class QNetworkManagerInterfaceDevicePrivate @@ -291,18 +395,39 @@ public: }; QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { + d = new QNetworkManagerInterfaceDevicePrivate(); d->path = deviceObjectPath; d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE), - QDBusConnection::systemBus()); + QDBusConnection::systemBus(),parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; } + QDBusInterface devicePropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus(),parent); + + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE); + QDBusPendingReply<QVariantMap> propsReply + = devicePropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); d->valid = true; } @@ -319,35 +444,10 @@ bool QNetworkManagerInterfaceDevice::isValid() bool QNetworkManagerInterfaceDevice::setConnections() { - if(!isValid() ) + if (!isValid()) return false; - bool allOk = true; - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper,SIGNAL(pathForStateChanged(QString,quint32)), - this, SIGNAL(stateChanged(QString,quint32))); - - if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_DEVICE), - QLatin1String("StateChanged"), - nmDBusHelper,SLOT(deviceStateChanged(quint32)))) { - allOk = false; - } - - connect(nmDBusHelper, SIGNAL(pathForConnectionsChanged(QStringList)), - this,SIGNAL(connectionsChanged(QStringList))); - - if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), - QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>))) ) { - allOk = false; - } - - return allOk; + return true; } QDBusInterface *QNetworkManagerInterfaceDevice::connectionInterface() const @@ -357,33 +457,66 @@ QDBusInterface *QNetworkManagerInterfaceDevice::connectionInterface() const QString QNetworkManagerInterfaceDevice::udi() const { - return d->connectionInterface->property("Udi").toString(); + if (propertyMap.contains("Udi")) + return propertyMap.value("Udi").toString(); + return QString(); } QString QNetworkManagerInterfaceDevice::networkInterface() const { - return d->connectionInterface->property("Interface").toString(); + if (propertyMap.contains("Interface")) + return propertyMap.value("Interface").toString(); + return QString(); } quint32 QNetworkManagerInterfaceDevice::ip4Address() const { - return d->connectionInterface->property("Ip4Address").toUInt(); + if (propertyMap.contains("Ip4Address")) + return propertyMap.value("Ip4Address").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceDevice::state() const { - return d->connectionInterface->property("State").toUInt(); + if (propertyMap.contains("State")) + return propertyMap.value("State").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceDevice::deviceType() const { - return d->connectionInterface->property("DeviceType").toUInt(); + if (propertyMap.contains("DeviceType")) + return propertyMap.value("DeviceType").toUInt(); + return 0; } QDBusObjectPath QNetworkManagerInterfaceDevice::ip4config() const { - QVariant prop = d->connectionInterface->property("Ip4Config"); - return prop.value<QDBusObjectPath>(); + if (propertyMap.contains("Ip4Config")) + return propertyMap.value("Ip4Config").value<QDBusObjectPath>(); + return QDBusObjectPath(); +} + +void QNetworkManagerInterfaceDevice::propertiesSwap(QMap<QString,QVariant> map) +{ + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + if (i.key() == QStringLiteral("AvailableConnections")) { //Device + const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>(); + QDBusObjectPath path; + QStringList paths; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> path; + paths << path.path(); + } + dbusArgs.endArray(); + Q_EMIT connectionsChanged(paths); + } + propertyMap.insert(i.key(),i.value()); + } + Q_EMIT propertiesChanged(map); } class QNetworkManagerInterfaceDeviceWiredPrivate @@ -395,7 +528,7 @@ public: }; QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { d = new QNetworkManagerInterfaceDeviceWiredPrivate(); d->path = ifaceDevicePath; @@ -407,6 +540,27 @@ QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const Q d->valid = false; return; } + QDBusInterface deviceWiredPropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus(),parent); + + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED); + QDBusPendingReply<QVariantMap> propsReply + = deviceWiredPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); + d->valid = true; } @@ -424,23 +578,9 @@ bool QNetworkManagerInterfaceDeviceWired::isValid() bool QNetworkManagerInterfaceDeviceWired::setConnections() { - if(!isValid() ) + if (!isValid()) return false; - - bool allOk = true; - - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)), - this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>))); - if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED), - QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>))) ) { - allOk = false; - } - return allOk; + return true; } QDBusInterface *QNetworkManagerInterfaceDeviceWired::connectionInterface() const @@ -450,17 +590,53 @@ QDBusInterface *QNetworkManagerInterfaceDeviceWired::connectionInterface() const QString QNetworkManagerInterfaceDeviceWired::hwAddress() const { - return d->connectionInterface->property("HwAddress").toString(); + if (propertyMap.contains("HwAddress")) + return propertyMap.value("HwAddress").toString(); + return QString(); } quint32 QNetworkManagerInterfaceDeviceWired::speed() const { - return d->connectionInterface->property("Speed").toUInt(); + if (propertyMap.contains("Speed")) + return propertyMap.value("Speed").toUInt(); + return 0; } bool QNetworkManagerInterfaceDeviceWired::carrier() const { - return d->connectionInterface->property("Carrier").toBool(); + if (propertyMap.contains("Carrier")) + return propertyMap.value("Carrier").toBool(); + return false; +} + +QStringList QNetworkManagerInterfaceDeviceWired::availableConnections() +{ + QStringList list; + if (propertyMap.contains("AvailableConnections")) { + const QDBusArgument &dbusArgs = propertyMap.value("Carrier").value<QDBusArgument>(); + QDBusObjectPath path; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> path; + list << path.path(); + } + dbusArgs.endArray(); + } + + return list; +} + +void QNetworkManagerInterfaceDeviceWired::propertiesSwap(QMap<QString,QVariant> map) +{ + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + propertyMap.insert(i.key(),i.value()); + if (i.key() == QStringLiteral("Carrier")) { + Q_EMIT carrierChanged(i.value().toBool()); + } + } + Q_EMIT propertiesChanged(map); } class QNetworkManagerInterfaceDeviceWirelessPrivate @@ -472,7 +648,7 @@ public: }; QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { d = new QNetworkManagerInterfaceDeviceWirelessPrivate(); d->path = ifaceDevicePath; @@ -484,6 +660,34 @@ QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(c d->valid = false; return; } + + + QDBusPendingReply<QList <QDBusObjectPath> > nmReply + = d->connectionInterface->call(QLatin1String("GetAccessPoints")); + + if (!nmReply.isError()) { + accessPointsList = nmReply.value(); + } + + QDBusInterface deviceWirelessPropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus(),parent); + + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS); + QDBusPendingReply<QVariantMap> propsReply + = deviceWirelessPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); d->valid = true; } @@ -498,29 +702,31 @@ bool QNetworkManagerInterfaceDeviceWireless::isValid() return d->valid; } +void QNetworkManagerInterfaceDeviceWireless::slotAccessPointAdded(QDBusObjectPath path) +{ + if (path.path().length() > 2) + Q_EMIT accessPointAdded(path.path()); +} + +void QNetworkManagerInterfaceDeviceWireless::slotAccessPointRemoved(QDBusObjectPath path) +{ + if (path.path().length() > 2) + Q_EMIT accessPointRemoved(path.path()); +} + bool QNetworkManagerInterfaceDeviceWireless::setConnections() { - if(!isValid() ) + if (!isValid()) return false; QDBusConnection dbusConnection = QDBusConnection::systemBus(); bool allOk = true; - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)), - this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>))); - - connect(nmDBusHelper, SIGNAL(pathForAccessPointAdded(QString)), - this,SIGNAL(accessPointAdded(QString))); - - connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(QString)), - this,SIGNAL(accessPointRemoved(QString))); if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), - d->path, + d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("AccessPointAdded"), - nmDBusHelper, SLOT(slotAccessPointAdded(QDBusObjectPath)))) { + this, SLOT(slotAccessPointAdded(QDBusObjectPath)))) { allOk = false; } @@ -529,18 +735,10 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections() d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("AccessPointRemoved"), - nmDBusHelper, SLOT(slotAccessPointRemoved(QDBusObjectPath)))) { + this, SLOT(slotAccessPointRemoved(QDBusObjectPath)))) { allOk = false; } - - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), - QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>)))) { - allOk = false; - } if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), @@ -558,33 +756,48 @@ QDBusInterface *QNetworkManagerInterfaceDeviceWireless::connectionInterface() co QList <QDBusObjectPath> QNetworkManagerInterfaceDeviceWireless::getAccessPoints() { - QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("GetAccessPoints")); - return reply.value(); + if (accessPointsList.isEmpty()) { + qWarning() << "Using blocking call!"; + QDBusReply<QList<QDBusObjectPath> > reply + = d->connectionInterface->call(QLatin1String("GetAccessPoints")); + accessPointsList = reply.value(); + } + return accessPointsList; } QString QNetworkManagerInterfaceDeviceWireless::hwAddress() const { - return d->connectionInterface->property("HwAddress").toString(); + if (propertyMap.contains("HwAddress")) + return propertyMap.value("HwAddress").toString(); + return QString(); } quint32 QNetworkManagerInterfaceDeviceWireless::mode() const { - return d->connectionInterface->property("Mode").toUInt(); + if (propertyMap.contains("Mode")) + return propertyMap.value("Mode").toUInt(); + return 0; } quint32 QNetworkManagerInterfaceDeviceWireless::bitrate() const { - return d->connectionInterface->property("Bitrate").toUInt(); + if (propertyMap.contains("Bitrate")) + return propertyMap.value("Bitrate").toUInt(); + return 0; } QDBusObjectPath QNetworkManagerInterfaceDeviceWireless::activeAccessPoint() const { - return d->connectionInterface->property("ActiveAccessPoint").value<QDBusObjectPath>(); + if (propertyMap.contains("ActiveAccessPoint")) + return propertyMap.value("ActiveAccessPoint").value<QDBusObjectPath>(); + return QDBusObjectPath(); } quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const { - return d->connectionInterface->property("WirelelessCapabilities").toUInt(); + if (propertyMap.contains("WirelelessCapabilities")) + return propertyMap.value("WirelelessCapabilities").toUInt(); + return 0; } void QNetworkManagerInterfaceDeviceWireless::scanIsDone() @@ -597,6 +810,17 @@ void QNetworkManagerInterfaceDeviceWireless::requestScan() d->connectionInterface->asyncCall(QLatin1String("RequestScan")); } +void QNetworkManagerInterfaceDeviceWireless::propertiesSwap(QMap<QString,QVariant> map) +{ + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + propertyMap.insert(i.key(),i.value()); + if (i.key() == QStringLiteral("ActiveAccessPoint")) { //DeviceWireless + Q_EMIT propertiesChanged(map); + } + } +} class QNetworkManagerInterfaceDeviceModemPrivate { @@ -607,7 +831,7 @@ public: }; QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { d = new QNetworkManagerInterfaceDeviceModemPrivate(); d->path = ifaceDevicePath; @@ -619,6 +843,25 @@ QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const Q d->valid = false; return; } + QDBusInterface deviceModemPropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus(),parent); + + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM); + QDBusPendingReply<QVariantMap> propsReply + = deviceModemPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); d->valid = true; } @@ -639,20 +882,7 @@ bool QNetworkManagerInterfaceDeviceModem::setConnections() if (!isValid() ) return false; - bool allOk = true; - - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)), - this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>))); - if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM), - QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(slotDevicePropertiesChanged(QMap<QString,QVariant>))) ) { - allOk = false; - } - return allOk; + return true; } QDBusInterface *QNetworkManagerInterfaceDeviceModem::connectionInterface() const @@ -660,14 +890,28 @@ QDBusInterface *QNetworkManagerInterfaceDeviceModem::connectionInterface() const return d->connectionInterface; } -quint32 QNetworkManagerInterfaceDeviceModem::modemCapabilities() const +QNetworkManagerInterfaceDeviceModem::ModemCapabilities QNetworkManagerInterfaceDeviceModem::modemCapabilities() const +{ + if (propertyMap.contains("ModemCapabilities")) + return static_cast<QNetworkManagerInterfaceDeviceModem::ModemCapabilities>(propertyMap.value("ModemCapabilities").toUInt()); + return QNetworkManagerInterfaceDeviceModem::None; +} + +QNetworkManagerInterfaceDeviceModem::ModemCapabilities QNetworkManagerInterfaceDeviceModem::currentCapabilities() const { - return d->connectionInterface->property("ModemCapabilities").toUInt(); + if (propertyMap.contains("CurrentCapabilities")) + return static_cast<QNetworkManagerInterfaceDeviceModem::ModemCapabilities>(propertyMap.value("CurrentCapabilities").toUInt()); + return QNetworkManagerInterfaceDeviceModem::None; } -quint32 QNetworkManagerInterfaceDeviceModem::currentCapabilities() const +void QNetworkManagerInterfaceDeviceModem::propertiesSwap(QMap<QString,QVariant> map) { - return d->connectionInterface->property("CurrentCapabilities").toUInt(); + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + propertyMap.insert(i.key(),i.value()); + } + Q_EMIT propertiesChanged(map); } class QNetworkManagerSettingsPrivate @@ -691,6 +935,14 @@ QNetworkManagerSettings::QNetworkManagerSettings(const QString &settingsService, d->valid = false; return; } + + QDBusPendingReply<QList <QDBusObjectPath> > nmReply + = d->connectionInterface->call(QLatin1String("ListConnections")); + + if (!nmReply.isError()) { + connectionsList = nmReply.value(); + } + d->valid = true; } @@ -722,10 +974,16 @@ bool QNetworkManagerSettings::setConnections() QList <QDBusObjectPath> QNetworkManagerSettings::listConnections() { - QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("ListConnections")); - return reply.value(); + if (connectionsList.isEmpty()) { + qWarning() << "Using blocking call!"; + QDBusReply<QList<QDBusObjectPath> > reply + = d->connectionInterface->call(QLatin1String("ListConnections")); + connectionsList = reply.value(); + } + return connectionsList; } + QString QNetworkManagerSettings::getConnectionByUuid(const QString &uuid) { QList<QVariant> argumentList; @@ -751,7 +1009,7 @@ public: }; QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { qDBusRegisterMetaType<QNmSettingsMap>(); d = new QNetworkManagerSettingsConnectionPrivate(); @@ -766,8 +1024,12 @@ QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QStri return; } d->valid = true; - QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call(QLatin1String("GetSettings")); - d->settingsMap = rep.value(); + + QDBusPendingReply<QNmSettingsMap> nmReply + = d->connectionInterface->call(QLatin1String("GetSettings")); + if (!nmReply.isError()) { + d->settingsMap = nmReply.value(); + } } QNetworkManagerSettingsConnection::~QNetworkManagerSettingsConnection() @@ -783,7 +1045,7 @@ bool QNetworkManagerSettingsConnection::isValid() bool QNetworkManagerSettingsConnection::setConnections() { - if(!isValid() ) + if (!isValid()) return false; QDBusConnection dbusConnection = QDBusConnection::systemBus(); @@ -796,21 +1058,21 @@ bool QNetworkManagerSettingsConnection::setConnections() allOk = false; } - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForSettingsRemoved(QString)), - this,SIGNAL(removed(QString))); - if (!dbusConnection.connect(d->service, d->path, QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), QLatin1String("Removed"), - nmDBusHelper, SIGNAL(slotSettingsRemoved()))) { + this, SIGNAL(slotSettingsRemoved()))) { allOk = false; } return allOk; } +void QNetworkManagerSettingsConnection::slotSettingsRemoved() +{ + Q_EMIT removed(d->path); +} + QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const { return d->connectionInterface; @@ -818,8 +1080,11 @@ QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const QNmSettingsMap QNetworkManagerSettingsConnection::getSettings() { - QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call(QLatin1String("GetSettings")); - d->settingsMap = rep.value(); + if (d->settingsMap.isEmpty()) { + qWarning() << "Using blocking call!"; + QDBusReply<QNmSettingsMap> reply = d->connectionInterface->call(QLatin1String("GetSettings")); + d->settingsMap = reply.value(); + } return d->settingsMap; } @@ -832,6 +1097,8 @@ NMDeviceType QNetworkManagerSettingsConnection::getType() return DEVICE_TYPE_ETHERNET; else if (devType == QLatin1String("802-11-wireless")) return DEVICE_TYPE_WIFI; + else if (devType == QLatin1String("gsm")) + return DEVICE_TYPE_MODEM; else return DEVICE_TYPE_UNKNOWN; } @@ -908,7 +1175,7 @@ public: }; QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString &activeConnectionObjectPath, QObject *parent) - : QObject(parent), nmDBusHelper(0) + : QObject(parent) { d = new QNetworkManagerConnectionActivePrivate(); d->path = activeConnectionObjectPath; @@ -920,6 +1187,29 @@ QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString & d->valid = false; return; } + QDBusInterface connectionActivePropertiesInterface(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus()); + + + QList<QVariant> argumentList; + argumentList << QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION); + QDBusPendingReply<QVariantMap> propsReply + = connectionActivePropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), + argumentList); + + if (!propsReply.isError()) { + propertyMap = propsReply.value(); + } else { + qWarning() << propsReply.error().message(); + } + + QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), + d->path, + QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap<QString,QVariant>))); d->valid = true; } @@ -936,24 +1226,10 @@ bool QNetworkManagerConnectionActive::isValid() bool QNetworkManagerConnectionActive::setConnections() { - if(!isValid() ) + if (!isValid()) return false; - bool allOk = true; - delete nmDBusHelper; - nmDBusHelper = new QNmDBusHelper(this); - connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)), - this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>))); - - if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - d->path, - QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION), - QLatin1String("PropertiesChanged"), - nmDBusHelper,SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>))) ) { - allOk = false; - } - - return allOk; + return true; } QDBusInterface *QNetworkManagerConnectionActive::connectionInterface() const @@ -963,30 +1239,70 @@ QDBusInterface *QNetworkManagerConnectionActive::connectionInterface() const QDBusObjectPath QNetworkManagerConnectionActive::connection() const { - QVariant prop = d->connectionInterface->property("Connection"); - return prop.value<QDBusObjectPath>(); + if (propertyMap.contains("Connection")) + return propertyMap.value("Connection").value<QDBusObjectPath>(); + return QDBusObjectPath(); } QDBusObjectPath QNetworkManagerConnectionActive::specificObject() const { - QVariant prop = d->connectionInterface->property("SpecificObject"); - return prop.value<QDBusObjectPath>(); + if (propertyMap.contains("SpecificObject")) + return propertyMap.value("SpecificObject").value<QDBusObjectPath>(); + return QDBusObjectPath(); } -QList<QDBusObjectPath> QNetworkManagerConnectionActive::devices() const +QStringList QNetworkManagerConnectionActive::devices() const { - QVariant prop = d->connectionInterface->property("Devices"); - return prop.value<QList<QDBusObjectPath> >(); + QStringList list; + if (propertyMap.contains("Devices")) { + const QDBusArgument &dbusArgs = propertyMap.value("Devices").value<QDBusArgument>(); + QDBusObjectPath path; + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> path; + list.append(path.path()); + } + dbusArgs.endArray(); + } + return list; } quint32 QNetworkManagerConnectionActive::state() const { - return d->connectionInterface->property("State").toUInt(); + if (propertyMap.contains("State")) + return propertyMap.value("State").toUInt(); + return 0; } bool QNetworkManagerConnectionActive::defaultRoute() const { - return d->connectionInterface->property("Default").toBool(); + if (propertyMap.contains("Default")) + return propertyMap.value("Default").toBool(); + return false; +} + +bool QNetworkManagerConnectionActive::default6Route() const +{ + if (propertyMap.contains("Default6")) + return propertyMap.value("Default6").toBool(); + return false; +} + +void QNetworkManagerConnectionActive::propertiesSwap(QMap<QString,QVariant> map) +{ + QMapIterator<QString, QVariant> i(map); + while (i.hasNext()) { + i.next(); + propertyMap.insert(i.key(),i.value()); + if (i.key() == QStringLiteral("State")) { + quint32 state = i.value().toUInt(); + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED + || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { + Q_EMIT propertiesChanged(map); + } + } + } } class QNetworkManagerIp4ConfigPrivate diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 11ddaf7088..da909c443a 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -56,7 +56,6 @@ #include <QtDBus/QDBusObjectPath> #include <QtDBus/QDBusContext> #include <QMap> -#include "qnmdbushelper.h" #ifndef QT_NO_DBUS @@ -89,7 +88,7 @@ typedef enum NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0, NM_ACTIVE_CONNECTION_STATE_ACTIVATING, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NM_ACTIVE_CONNECTION_STATE_DEACTIVATED + NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4 } NMActiveConnectionState; #define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" @@ -135,12 +134,23 @@ class QNetworkManagerInterface : public QObject Q_OBJECT public: + typedef enum + { + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP = 10, + NM_STATE_DISCONNECTED = 20, + NM_STATE_DISCONNECTING = 30, + NM_STATE_CONNECTING = 40, + NM_STATE_CONNECTED_LOCAL = 50, + NM_STATE_CONNECTED_SITE = 60, + NM_STATE_CONNECTED_GLOBAL = 70 + } NMState; QNetworkManagerInterface(QObject *parent = 0); ~QNetworkManagerInterface(); - QList <QDBusObjectPath> getDevices() const; - void activateConnection(const QString &serviceName, QDBusObjectPath connection, QDBusObjectPath device, QDBusObjectPath specificObject); + QList <QDBusObjectPath> getDevices(); + void activateConnection(QDBusObjectPath connection,QDBusObjectPath device, QDBusObjectPath specificObject); void deactivateConnection(QDBusObjectPath connectionPath) const; QDBusObjectPath path() const; @@ -149,21 +159,28 @@ public: bool wirelessEnabled() const; bool wirelessHardwareEnabled() const; QList <QDBusObjectPath> activeConnections() const; - quint32 state(); + NMState state(); + QString version() const; bool setConnections(); bool isValid(); Q_SIGNALS: void deviceAdded(QDBusObjectPath); void deviceRemoved(QDBusObjectPath); - void propertiesChanged( const QString &, QMap<QString,QVariant>); - void stateChanged(const QString&, quint32); + void propertiesChanged(QMap<QString,QVariant>); + void stateChanged(quint32); void activationFinished(QDBusPendingCallWatcher*); + void propertiesReady(); + void devicesListReady(); private Q_SLOTS: + void propertiesSwap(QMap<QString,QVariant>); + private: QNetworkManagerInterfacePrivate *d; - QNmDBusHelper *nmDBusHelper; + QVariantMap propertyMap; + QList<QDBusObjectPath> devicesPathList; + }; class QNetworkManagerInterfaceAccessPointPrivate; @@ -228,11 +245,14 @@ public: Q_SIGNALS: void propertiesChanged(QMap <QString,QVariant>); - void propertiesChanged( const QString &, QMap<QString,QVariant>); + void propertiesReady(); + +private Q_SLOTS: + void propertiesSwap(QMap<QString,QVariant>); + private: QNetworkManagerInterfaceAccessPointPrivate *d; - QNmDBusHelper *nmDBusHelper; - + QVariantMap propertyMap; }; class QNetworkManagerInterfaceDevicePrivate; @@ -258,11 +278,14 @@ public: Q_SIGNALS: void stateChanged(const QString &, quint32); - void propertiesChanged(const QString &, QMap<QString,QVariant>); + void propertiesChanged(QMap<QString,QVariant>); void connectionsChanged(QStringList); + void propertiesReady(); +private Q_SLOTS: + void propertiesSwap(QMap<QString,QVariant>); private: QNetworkManagerInterfaceDevicePrivate *d; - QNmDBusHelper *nmDBusHelper; + QVariantMap propertyMap; }; class QNetworkManagerInterfaceDeviceWiredPrivate; @@ -282,12 +305,19 @@ public: bool carrier() const; bool setConnections(); bool isValid(); + QStringList availableConnections(); Q_SIGNALS: - void propertiesChanged( const QString &, QMap<QString,QVariant>); + void propertiesChanged(QMap<QString,QVariant>); + void propertiesReady(); + void carrierChanged(bool); + +private Q_SLOTS: + void propertiesSwap(QMap<QString,QVariant>); + private: QNetworkManagerInterfaceDeviceWiredPrivate *d; - QNmDBusHelper *nmDBusHelper; + QVariantMap propertyMap; }; class QNetworkManagerInterfaceDeviceWirelessPrivate; @@ -325,15 +355,24 @@ public: void requestScan(); Q_SIGNALS: - void propertiesChanged( const QString &, QMap<QString,QVariant>); + void propertiesChanged(QMap<QString,QVariant>); void accessPointAdded(const QString &); void accessPointRemoved(const QString &); void scanDone(); + void propertiesReady(); + void accessPointsReady(); + private Q_SLOTS: void scanIsDone(); + void propertiesSwap(QMap<QString,QVariant>); + + void slotAccessPointAdded(QDBusObjectPath); + void slotAccessPointRemoved(QDBusObjectPath); + private: QNetworkManagerInterfaceDeviceWirelessPrivate *d; - QNmDBusHelper *nmDBusHelper; + QVariantMap propertyMap; + QList <QDBusObjectPath> accessPointsList; }; class QNetworkManagerInterfaceDeviceModemPrivate; @@ -350,6 +389,7 @@ public: Gsm_Umts = 0x4, Lte = 0x08 }; + Q_DECLARE_FLAGS(ModemCapabilities, ModemCapability) explicit QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, QObject *parent = 0); @@ -361,16 +401,22 @@ public: bool setConnections(); bool isValid(); - quint32 modemCapabilities() const; - quint32 currentCapabilities() const; + ModemCapabilities modemCapabilities() const; + ModemCapabilities currentCapabilities() const; Q_SIGNALS: - void propertiesChanged( const QString &, QMap<QString,QVariant>); + void propertiesChanged(QMap<QString,QVariant>); + void propertiesReady(); + +private Q_SLOTS: + void propertiesSwap(QMap<QString,QVariant>); + private: QNetworkManagerInterfaceDeviceModemPrivate *d; - QNmDBusHelper *nmDBusHelper; + QVariantMap propertyMap; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkManagerInterfaceDeviceModem::ModemCapabilities) class QNetworkManagerSettingsPrivate; class QNetworkManagerSettings : public QObject @@ -390,8 +436,10 @@ public: Q_SIGNALS: void newConnection(QDBusObjectPath); + void connectionsListReady(); private: QNetworkManagerSettingsPrivate *d; + QList <QDBusObjectPath> connectionsList; }; class QNetworkManagerSettingsConnectionPrivate; @@ -418,12 +466,14 @@ public: bool isValid(); Q_SIGNALS: - void updated(); void removed(const QString &path); + void settingsReady(); + +private Q_SLOTS: + void slotSettingsRemoved(); private: - QNmDBusHelper *nmDBusHelper; QNetworkManagerSettingsConnectionPrivate *d; }; @@ -444,22 +494,26 @@ public: ~ QNetworkManagerConnectionActive(); QDBusInterface *connectionInterface() const; - QString serviceName() const; QDBusObjectPath connection() const; QDBusObjectPath specificObject() const; - QList<QDBusObjectPath> devices() const; + QStringList devices() const; quint32 state() const; bool defaultRoute() const; + bool default6Route() const; bool setConnections(); bool isValid(); Q_SIGNALS: - void propertiesChanged(QList<QDBusObjectPath>); - void propertiesChanged( const QString &, QMap<QString,QVariant>); + void propertiesChanged(QMap<QString,QVariant>); + void propertiesReady(); + +private Q_SLOTS: + void propertiesSwap(QMap<QString,QVariant>); + private: QNetworkManagerConnectionActivePrivate *d; - QNmDBusHelper *nmDBusHelper; + QVariantMap propertyMap; }; class QNetworkManagerIp4ConfigPrivate; diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp deleted file mode 100644 index 0decfd78b9..0000000000 --- a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** 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. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// this class is for helping qdbus get stuff - -#include "qnmdbushelper.h" - -#include "qnetworkmanagerservice.h" - -#include <QDBusError> -#include <QDBusInterface> -#include <QDBusMessage> -#include <QDBusReply> - -#include <QDebug> - -#ifndef QT_NO_DBUS - -QT_BEGIN_NAMESPACE - -QNmDBusHelper::QNmDBusHelper(QObject * parent) - : QObject(parent) -{ -} - -QNmDBusHelper::~QNmDBusHelper() -{ -} - -void QNmDBusHelper::deviceStateChanged(quint32 state) - { - QDBusMessage msg = this->message(); - if (state == NM_DEVICE_STATE_ACTIVATED - || state == NM_DEVICE_STATE_DISCONNECTED - || state == NM_DEVICE_STATE_UNAVAILABLE - || state == NM_DEVICE_STATE_FAILED) { - emit pathForStateChanged(msg.path(), state); - } - } - -void QNmDBusHelper::slotAccessPointAdded(QDBusObjectPath path) -{ - if (path.path().length() > 2) - emit pathForAccessPointAdded(path.path()); -} - -void QNmDBusHelper::slotAccessPointRemoved(QDBusObjectPath path) -{ - if (path.path().length() > 2) - emit pathForAccessPointRemoved(path.path()); -} - -void QNmDBusHelper::slotPropertiesChanged(QMap<QString,QVariant> map) -{ - QDBusMessage msg = this->message(); - QMapIterator<QString, QVariant> i(map); - while (i.hasNext()) { - i.next(); - if (i.key() == QStringLiteral("State")) { - quint32 state = i.value().toUInt(); - if (state == NM_DEVICE_STATE_ACTIVATED - || state == NM_DEVICE_STATE_DISCONNECTED - || state == NM_DEVICE_STATE_UNAVAILABLE - || state == NM_DEVICE_STATE_FAILED) { - emit pathForPropertiesChanged(msg.path(), map); - } - } else if (i.key() == QStringLiteral("ActiveAccessPoint")) { - emit pathForPropertiesChanged(msg.path(), map); - } else if (i.key() == QStringLiteral("ActiveConnections")) { - emit pathForPropertiesChanged(msg.path(), map); - } else if (i.key() == QStringLiteral("AvailableConnections")) { - const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>(); - QDBusObjectPath path; - QStringList paths; - dbusArgs.beginArray(); - while (!dbusArgs.atEnd()) { - dbusArgs >> path; - paths << path.path(); - } - dbusArgs.endArray(); - emit pathForConnectionsChanged(paths); - } - } -} - -void QNmDBusHelper::slotSettingsRemoved() -{ - QDBusMessage msg = this->message(); - emit pathForSettingsRemoved(msg.path()); -} - -void QNmDBusHelper::activeConnectionPropertiesChanged(QMap<QString,QVariant> map) -{ - QDBusMessage msg = this->message(); - QMapIterator<QString, QVariant> i(map); - while (i.hasNext()) { - i.next(); - if (i.key() == QStringLiteral("State")) { - quint32 state = i.value().toUInt(); - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED - || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { - emit pathForPropertiesChanged(msg.path(), map); - } - } - } -} - -QT_END_NAMESPACE - -#endif // QT_NO_DBUS diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.h b/src/plugins/bearer/networkmanager/qnmdbushelper.h deleted file mode 100644 index e224af87f1..0000000000 --- a/src/plugins/bearer/networkmanager/qnmdbushelper.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** 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. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNMDBUSHELPERPRIVATE_H -#define QNMDBUSHELPERPRIVATE_H - -#include <QDBusObjectPath> -#include <QDBusContext> -#include <QMap> - -#ifndef QT_NO_DBUS - -QT_BEGIN_NAMESPACE - -class QNmDBusHelper: public QObject, protected QDBusContext - { - Q_OBJECT - public: - QNmDBusHelper(QObject *parent = 0); - ~QNmDBusHelper(); - - public slots: - void deviceStateChanged(quint32); - void slotAccessPointAdded(QDBusObjectPath); - void slotAccessPointRemoved(QDBusObjectPath); - void slotPropertiesChanged(QMap<QString,QVariant>); - void slotSettingsRemoved(); - void activeConnectionPropertiesChanged(QMap<QString,QVariant>); - -Q_SIGNALS: - void pathForStateChanged(const QString &, quint32); - void pathForAccessPointAdded(const QString &); - void pathForAccessPointRemoved(const QString &); - void pathForPropertiesChanged(const QString &, QMap<QString,QVariant>); - void pathForSettingsRemoved(const QString &); - void pathForConnectionsChanged(const QStringList &pathsList); -}; - -QT_END_NAMESPACE - -#endif // QT_NO_DBUS - -#endif// QNMDBUSHELPERPRIVATE_H diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index 1db59fec94..c5adc98af7 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -366,7 +366,8 @@ void QNetworkSessionPrivateImpl::networkConfigurationsChanged() else updateStateFromActiveConfig(); - startTime = engine->startTime(activeConfig.identifier()); + if (engine) + startTime = engine->startTime(activeConfig.identifier()); } void QNetworkSessionPrivateImpl::configurationChanged(QNetworkConfigurationPrivatePointer config) diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp index 9bc53ed5c0..ec8c746b2d 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include "qibustypes.h" -#include <qtextformat.h> #include <QtDBus> #include <QHash> @@ -134,7 +133,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusAttribute &a return argument; } -QTextFormat QIBusAttribute::format() const +QTextCharFormat QIBusAttribute::format() const { QTextCharFormat fmt; switch (type) { @@ -225,11 +224,32 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const { + QHash<QPair<int, int>, QTextCharFormat> rangeAttrs; + + // Merge text fomats for identical ranges into a single QTextFormat. + for (int i = 0; i < attributes.size(); ++i) { + const QIBusAttribute &attr = attributes.at(i); + const QTextCharFormat &format = attr.format(); + + if (format.isValid()) { + const QPair<int, int> range(attr.start, attr.end); + rangeAttrs[range].merge(format); + } + } + + // Assemble list in original attribute order. QList<QInputMethodEvent::Attribute> imAttrs; + for (int i = 0; i < attributes.size(); ++i) { const QIBusAttribute &attr = attributes.at(i); - imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format()); + const QTextFormat &format = attr.format(); + + imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, + attr.start, + attr.end - attr.start, + format.isValid() ? rangeAttrs[QPair<int, int>(attr.start, attr.end)] : format); } + return imAttrs; } diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h index 2ec3b019ff..96791b17a1 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.h +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h @@ -36,6 +36,7 @@ #include <qvector.h> #include <qevent.h> #include <QDBusArgument> +#include <QTextCharFormat> QT_BEGIN_NAMESPACE @@ -70,7 +71,7 @@ public: QIBusAttribute(); ~QIBusAttribute(); - QTextFormat format() const; + QTextCharFormat format() const; Type type; quint32 value; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index a43cf73d34..b232c7a4d3 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -268,6 +268,7 @@ public: // for QNSView bool m_inConstructor; bool m_inSetVisible; + bool m_inSetGeometry; #ifndef QT_NO_OPENGL QCocoaGLContext *m_glContext; #endif diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f536e20b39..6656212457 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -381,6 +381,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_windowUnderMouse(false) , m_inConstructor(true) , m_inSetVisible(false) + , m_inSetGeometry(false) #ifndef QT_NO_OPENGL , m_glContext(0) #endif @@ -470,6 +471,8 @@ QSurfaceFormat QCocoaWindow::format() const void QCocoaWindow::setGeometry(const QRect &rectIn) { + QBoolBlocker inSetGeometry(m_inSetGeometry, true); + QRect rect = rectIn; // This means it is a call from QWindow::setFramePosition() and // the coordinates include the frame (size is still the contents rectangle). @@ -1754,6 +1757,11 @@ void QCocoaWindow::updateExposedGeometry() if (!m_geometryUpdateExposeAllowed) return; + // Do not send incorrect exposes in case the window is not even visible yet. + // We might get here as a result of a resize() from QWidget's show(), for instance. + if (!window()->isVisible()) + return; + if (!isWindowExposable()) return; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index fa85a2bf54..699340795d 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -361,12 +361,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; // Send a geometry change event to Qt, if it's ready to handle events if (!m_platformWindow->m_inConstructor) { QWindowSystemInterface::handleGeometryChange(m_window, geometry); - // Do not send incorrect exposes in case the window is not even visible yet. - // We might get here as a result of a resize() from QWidget's show(), for instance. - if (m_platformWindow->window()->isVisible()) { - m_platformWindow->updateExposedGeometry(); + m_platformWindow->updateExposedGeometry(); + // Guard against processing window system events during QWindow::setGeometry + // calles, which Qt and Qt applications do not excpect. + if (!m_platformWindow->m_inSetGeometry) QWindowSystemInterface::flushWindowSystemEvents(); - } } } @@ -603,7 +602,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; { if (m_window->flags() & Qt::WindowTransparentForInput) return NO; - QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); + if (!m_platformWindow->windowIsPopupType()) + QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); return YES; } @@ -662,6 +662,19 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; m_frameStrutButtons = Qt::NoButton; } +- (NSPoint) screenMousePoint:(NSEvent *)theEvent +{ + NSPoint screenPoint; + if (theEvent) { + NSPoint windowPoint = [theEvent locationInWindow]; + NSRect screenRect = [[theEvent window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)]; + screenPoint = screenRect.origin; + } else { + screenPoint = [NSEvent mouseLocation]; + } + return screenPoint; +} + - (void)handleMouseEvent:(NSEvent *)theEvent { [self handleTabletEvent: theEvent]; @@ -676,23 +689,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; m_platformWindow->m_forwardWindow = 0; } - NSPoint globalPos = [NSEvent mouseLocation]; - - if ([self.window parentWindow] - && (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)) { - // QToolBar can be implemented as a child window on top of its main window - // (with a borderless NSWindow). If an option "unified toolbar" set on the main window, - // it's possible to drag such a window using this toolbar. - // While handling mouse drag events, QToolBar moves the window (QWidget::move). - // In such a combination [NSEvent mouseLocation] is very different from the - // real event location and as a result a window will move chaotically. - NSPoint winPoint = [theEvent locationInWindow]; - NSRect tmpRect = NSMakeRect(winPoint.x, winPoint.y, 1., 1.); - tmpRect = [[theEvent window] convertRectToScreen:tmpRect]; - globalPos = tmpRect.origin; - } - - [targetView convertFromScreen:globalPos toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; + [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; ulong timestamp = [theEvent timestamp] * 1000; QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); @@ -865,7 +862,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; QPointF windowPoint; QPointF screenPoint; - [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint()); // Top-level windows generate enter-leave events for sub-windows. diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index b6b1be9244..26d77a2abb 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -63,11 +63,13 @@ QByteArray QEglFSHooks::fbDeviceName() const int QEglFSHooks::framebufferIndex() const { int fbIndex = 0; +#ifndef QT_NO_REGULAREXPRESSION QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)")); QRegularExpressionMatch match = fbIndexRx.match(fbDeviceName()); if (match.hasMatch()) fbIndex = match.captured(1).toInt(); +#endif return fbIndex; } diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 66fd9cd1e5..ffffc4cbc4 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -317,11 +317,16 @@ static bool rootLevelRunLoopIntegration() } #if defined(Q_PROCESSOR_X86) -# define SET_STACK_POINTER "mov %0, %%esp" # define FUNCTION_CALL_ALIGNMENT 16 +# if defined(Q_PROCESSOR_X86_32) +# define SET_STACK_POINTER "mov %0, %%esp" +# elif defined(Q_PROCESSOR_X86_64) +# define SET_STACK_POINTER "movq %0, %%rsp" +# endif #elif defined(Q_PROCESSOR_ARM) -# define SET_STACK_POINTER "mov sp, %0" +# // Valid for both 32 and 64-bit ARM # define FUNCTION_CALL_ALIGNMENT 4 +# define SET_STACK_POINTER "mov sp, %0" #else # error "Unknown processor family" #endif diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index dbedba7e85..f7b9cd7015 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -62,7 +62,7 @@ QPointF fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); -QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen); + int infoPlistValue(NSString* key, int defaultValue); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 71d5a58088..9f10c3e287 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -127,15 +127,6 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } -QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen) -{ - // UIScreen is always in portrait. Use this function to convert CGRects - // aligned with UIScreen into whatever is the current orientation of QScreen. - QRect geometry = screen->geometry(); - return geometry.width() < geometry.height() ? rect - : QRect(rect.y(), geometry.height() - rect.width() - rect.x(), rect.height(), rect.width()); -} - int infoPlistValue(NSString* key, int defaultValue) { static NSBundle *bundle = [NSBundle mainBundle]; diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 5791367d84..1f1130f932 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -51,9 +51,10 @@ QT_BEGIN_NAMESPACE struct ImeState { - ImeState() : currentState(0) {} + ImeState() : currentState(0), focusObject(0) {} Qt::InputMethodQueries update(Qt::InputMethodQueries properties); QInputMethodQueryEvent currentState; + QObject *focusObject; }; class QIOSInputContext : public QPlatformInputContext @@ -82,6 +83,7 @@ public: void commit(); const ImeState &imeState() { return m_imeState; }; + bool inputMethodAccepted() const; bool isReloadingInputViewsFromUpdate() const { return m_isReloadingInputViewsFromUpdate; } diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index c038628fd9..072a49c7c5 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -46,25 +46,28 @@ #include "qiosglobal.h" #include "qiosintegration.h" #include "qiostextresponder.h" +#include "qiosviewcontroller.h" #include "qioswindow.h" #include "quiview.h" #include <QGuiApplication> #include <QtGui/private/qwindow_p.h> +// ------------------------------------------------------------------------- + static QUIView *focusView() { return qApp->focusWindow() ? reinterpret_cast<QUIView *>(qApp->focusWindow()->winId()) : 0; } -@interface QIOSKeyboardListener : UIGestureRecognizer { +// ------------------------------------------------------------------------- + +@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> { @public QIOSInputContext *m_context; BOOL m_keyboardVisible; BOOL m_keyboardVisibleAndDocked; - BOOL m_touchPressWhileKeyboardVisible; - BOOL m_keyboardHiddenByGesture; QRectF m_keyboardRect; CGRect m_keyboardEndRect; NSTimeInterval m_duration; @@ -77,13 +80,11 @@ static QUIView *focusView() - (id)initWithQIOSInputContext:(QIOSInputContext *)context { - self = [super initWithTarget:self action:@selector(gestureTriggered)]; + self = [super initWithTarget:self action:@selector(gestureStateChanged:)]; if (self) { m_context = context; m_keyboardVisible = NO; m_keyboardVisibleAndDocked = NO; - m_touchPressWhileKeyboardVisible = NO; - m_keyboardHiddenByGesture = NO; m_duration = 0; m_curve = UIViewAnimationCurveEaseOut; m_viewController = 0; @@ -99,10 +100,9 @@ static QUIView *focusView() Q_ASSERT(m_viewController); // Attach 'hide keyboard' gesture to the window, but keep it disabled when the - // keyboard is not visible. Note that we never trigger the gesture the way it is intended - // since we don't want to cancel touch events and interrupt flicking etc. Instead we use - // the gesture framework more as an event filter and hide the keyboard silently. + // keyboard is not visible. self.enabled = NO; + self.cancelsTouchesInView = NO; self.delaysTouchesEnded = NO; [m_viewController.view.window addGestureRecognizer:self]; } @@ -156,11 +156,19 @@ static QUIView *focusView() // Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked. m_keyboardVisibleAndDocked = YES; m_keyboardEndRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; - self.enabled = YES; + if (!m_duration) { m_duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; m_curve = UIViewAnimationCurve([[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]); } + + UIResponder *firstResponder = [UIResponder currentFirstResponder]; + if (![firstResponder isKindOfClass:[QIOSTextInputResponder class]]) + return; + + // Enable hide-keyboard gesture + self.enabled = YES; + m_context->scrollToCursor(); } @@ -169,7 +177,7 @@ static QUIView *focusView() // Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked. m_keyboardVisibleAndDocked = NO; m_keyboardEndRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; - if (!m_keyboardHiddenByGesture) { + if (self.state != UIGestureRecognizerStateBegan) { // Only disable the gesture if the hiding of the keyboard was not caused by it. // Otherwise we need to await the final touchEnd callback for doing some clean-up. self.enabled = NO; @@ -202,54 +210,81 @@ static QUIView *focusView() } } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +// ------------------------------------------------------------------------- + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - CGPoint p = [[touches anyObject] locationInView:m_viewController.view.window]; - if (CGRectContainsPoint(m_keyboardEndRect, p)) { - m_keyboardHiddenByGesture = YES; + [super touchesBegan:touches withEvent:event]; - UIResponder *firstResponder = [UIResponder currentFirstResponder]; - Q_ASSERT([firstResponder isKindOfClass:[QIOSTextInputResponder class]]); - [firstResponder resignFirstResponder]; - } + Q_ASSERT(m_keyboardVisibleAndDocked); - [super touchesMoved:touches withEvent:event]; + if ([touches count] != 1) + self.state = UIGestureRecognizerStateFailed; } -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - Q_ASSERT(m_keyboardVisibleAndDocked); - m_touchPressWhileKeyboardVisible = YES; - [super touchesBegan:touches withEvent:event]; + [super touchesMoved:touches withEvent:event]; + + if (self.state != UIGestureRecognizerStatePossible) + return; + + CGPoint touchPoint = [[touches anyObject] locationInView:m_viewController.view.window]; + if (CGRectContainsPoint(m_keyboardEndRect, touchPoint)) + self.state = UIGestureRecognizerStateBegan; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - m_touchPressWhileKeyboardVisible = NO; - [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO]; [super touchesEnded:touches withEvent:event]; + + [self touchesEndedOrCancelled]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - m_touchPressWhileKeyboardVisible = NO; - [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO]; [super touchesCancelled:touches withEvent:event]; + + [self touchesEndedOrCancelled]; +} + +- (void)touchesEndedOrCancelled +{ + // Defer final state change until next runloop iteration, so that Qt + // has a chance to process the final touch events first, before we eg. + // scroll the view. + dispatch_async(dispatch_get_main_queue (), ^{ + // iOS will transition from began to changed by itself + Q_ASSERT(self.state != UIGestureRecognizerStateBegan); + + if (self.state == UIGestureRecognizerStateChanged) + self.state = UIGestureRecognizerStateEnded; + else + self.state = UIGestureRecognizerStateFailed; + }); } -- (void)touchesEndedPostDelivery +- (void)gestureStateChanged:(id)sender { - // Do some clean-up _after_ touchEnd has been delivered to QUIView - m_keyboardHiddenByGesture = NO; + Q_UNUSED(sender); + + if (self.state == UIGestureRecognizerStateBegan) { + qImDebug() << "hide keyboard gesture was triggered"; + UIResponder *firstResponder = [UIResponder currentFirstResponder]; + Q_ASSERT([firstResponder isKindOfClass:[QIOSTextInputResponder class]]); + [firstResponder resignFirstResponder]; + } +} + +- (void)reset +{ + [super reset]; + if (!m_keyboardVisibleAndDocked) { + qImDebug() << "keyboard was hidden, disabling hide-keyboard gesture"; self.enabled = NO; - if (qApp->focusObject()) { - // UI Controls are told to gain focus on touch release. So when the 'hide keyboard' gesture - // finishes, the final touch end can trigger a control to gain focus. This is in conflict with - // the gesture, so we clear focus once more as a work-around. - static_cast<QWindowPrivate *>(QObjectPrivate::get(qApp->focusWindow()))->clearFocusObject(); - } } else { + qImDebug() << "gesture completed without triggering, scrolling view to cursor"; m_context->scrollToCursor(); } } @@ -265,8 +300,11 @@ Qt::InputMethodQueries ImeState::update(Qt::InputMethodQueries properties) QInputMethodQueryEvent newState(properties); - if (qApp && qApp->focusObject()) - QCoreApplication::sendEvent(qApp->focusObject(), &newState); + // Update the focus object that the new state is based on + focusObject = qApp ? qApp->focusObject() : 0; + + if (focusObject) + QCoreApplication::sendEvent(focusObject, &newState); Qt::InputMethodQueries updatedProperties; for (uint i = 0; i < (sizeof(Qt::ImQueryAll) * CHAR_BIT); ++i) { @@ -313,11 +351,23 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { // No-op, keyboard controlled fully by platform based on focus + qImDebug() << "can't show virtual keyboard without a focus object, ignoring"; } void QIOSInputContext::hideInputPanel() { - // No-op, keyboard controlled fully by platform based on focus + if (![m_textResponder isFirstResponder]) { + qImDebug() << "QIOSTextInputResponder is not first responder, ignoring"; + return; + } + + if (qGuiApp->focusObject() != m_imeState.focusObject) { + qImDebug() << "current focus object does not match IM state, likely hiding from focusOut event, so ignoring"; + return; + } + + qImDebug() << "hiding VKB as requested by QInputMethod::hide()"; + [m_textResponder resignFirstResponder]; } void QIOSInputContext::clearCurrentFocusObject() @@ -353,10 +403,10 @@ void QIOSInputContext::scrollToCursor() if (!isQtApplication()) return; - if (m_keyboardListener->m_touchPressWhileKeyboardVisible) { - // Don't scroll to the cursor if the user is touching the screen. This - // interferes with selection and the 'hide keyboard' gesture. Instead - // we update scrolling upon touchEnd. + if (m_keyboardListener.state == UIGestureRecognizerStatePossible && m_keyboardListener.numberOfTouches == 1) { + // Don't scroll to the cursor if the user is touching the screen and possibly + // trying to trigger the hide-keyboard gesture. + qImDebug() << "preventing scrolling to cursor as we're still waiting for a possible gesture"; return; } @@ -426,6 +476,18 @@ void QIOSInputContext::setFocusObject(QObject *focusObject) { Q_UNUSED(focusObject); + qImDebug() << "new focus object =" << focusObject; + + if (m_keyboardListener.state == UIGestureRecognizerStateChanged) { + // A new focus object may be set as part of delivering touch events to + // application during the hide-keyboard gesture, but we don't want that + // to result in a new object getting focus and bringing the keyboard up + // again. + qImDebug() << "clearing focus object" << focusObject << "as hide-keyboard gesture is active"; + clearCurrentFocusObject(); + return; + } + reset(); if (m_keyboardListener->m_keyboardVisibleAndDocked) @@ -436,6 +498,8 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow) { Q_UNUSED(focusWindow); + qImDebug() << "new focus window =" << focusWindow; + reset(); [m_keyboardListener handleKeyboardRectChanged]; @@ -486,6 +550,26 @@ void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties) } } +bool QIOSInputContext::inputMethodAccepted() const +{ + // The IM enablement state is based on the last call to update() + bool lastKnownImEnablementState = m_imeState.currentState.value(Qt::ImEnabled).toBool(); + +#if !defined(QT_NO_DEBUG) + // QPlatformInputContext keeps a cached value of the current IM enablement state that is + // updated by QGuiApplication when the current focus object changes, or by QInputMethod's + // update() function. If the focus object changes, but the change is not propagated as + // a signal to QGuiApplication due to bugs in the widget/graphicsview/qml stack, we'll + // end up with a stale value for QPlatformInputContext::inputMethodAccepted(). To be on + // the safe side we always use our own cached value to decide if IM is enabled, and try + // to detect the case where the two values are out of sync. + if (lastKnownImEnablementState != QPlatformInputContext::inputMethodAccepted()) + qWarning("QPlatformInputContext::inputMethodAccepted() does not match actual focus object IM enablement!"); +#endif + + return lastKnownImEnablementState; +} + /*! Called by the input item to reset the input method state. */ diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 4cbead44c5..f1f472b3e2 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1224,16 +1224,21 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters) QScopedArrayPointer<WCHAR> buffer(new WCHAR[totalStringLength + 2 * size]); QScopedArrayPointer<COMDLG_FILTERSPEC> comFilterSpec(new COMDLG_FILTERSPEC[size]); - const QString matchesAll = QStringLiteral(" (*)"); WCHAR *ptr = buffer.data(); // Split filter specification as 'Texts (*.txt[;] *.doc)' // into description and filters specification as '*.txt;*.doc' for (int i = 0; i < size; ++i) { - // Display glitch (CLSID only): 'All files (*)' shows up as 'All files (*) (*)' + // Display glitch (CLSID only): Any filter not filtering on suffix (such as + // '*', 'a.*') will be duplicated in combo: 'All files (*) (*)', + // 'AAA files (a.*) (a.*)' QString description = specs[i].description; - if (!m_hideFiltersDetails && description.endsWith(matchesAll)) - description.truncate(description.size() - matchesAll.size()); + const QString &filter = specs[i].filter; + if (!m_hideFiltersDetails && !filter.startsWith(QLatin1String("*."))) { + const int pos = description.lastIndexOf(QLatin1Char('(')); + if (pos > 0) + description.truncate(pos); + } // Add to buffer. comFilterSpec[i].pszName = ptr; ptr += description.toWCharArray(ptr); diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 7a6acf8b78..d20fbb558b 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -470,9 +470,10 @@ void QPpdPrintDevice::loadPrinter() m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance); if (m_cupsDest) { const char *ppdFile = cupsGetPPD(m_cupsName); - if (ppdFile) + if (ppdFile) { m_ppd = ppdOpenFile(ppdFile); - unlink(ppdFile); + unlink(ppdFile); + } if (m_ppd) { ppdMarkDefaults(m_ppd); } else { |