diff options
author | Olivier Goffart <ogoffart@trolltech.com> | 2010-03-25 19:27:05 (GMT) |
---|---|---|
committer | Olivier Goffart <ogoffart@trolltech.com> | 2010-03-25 19:27:05 (GMT) |
commit | 986873b239f15df43a3ebbc88a38f8ff8d6d07bf (patch) | |
tree | 946f585f390d3abb835a3280bbdc6bc90724977c /src/plugins | |
parent | b7f48eee301e973fcfae08dfd8997538b6dbe251 (diff) | |
parent | 3671dbf34940e166b747b6f8f3f5758fd486073c (diff) | |
download | Qt-986873b239f15df43a3ebbc88a38f8ff8d6d07bf.zip Qt-986873b239f15df43a3ebbc88a38f8ff8d6d07bf.tar.gz Qt-986873b239f15df43a3ebbc88a38f8ff8d6d07bf.tar.bz2 |
Merge remote branch 'origin/4.7' into 4.7
Conflicts:
tools/qdoc3/generator.cpp
tools/qdoc3/node.cpp
Diffstat (limited to 'src/plugins')
23 files changed, 678 insertions, 547 deletions
diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index 00be80e..f95e8af 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -1,14 +1,18 @@ TEMPLATE = subdirs -!maemo6:contains(QT_CONFIG, dbus) { - SUBDIRS += networkmanager generic +contains(QT_CONFIG, dbus) { + contains(QT_CONFIG, icd) { + SUBDIRS += icd + } else { + SUBDIRS += networkmanager generic + } } + #win32:SUBDIRS += nla win32:SUBDIRS += generic win32:!wince*:SUBDIRS += nativewifi macx:contains(QT_CONFIG, corewlan):SUBDIRS += corewlan macx:SUBDIRS += generic symbian:SUBDIRS += symbian -maemo6:contains(QT_CONFIG, dbus):SUBDIRS += icd isEmpty(SUBDIRS):SUBDIRS += generic diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro index 50c72b2..9786c03 100644 --- a/src/plugins/bearer/corewlan/corewlan.pro +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -6,7 +6,7 @@ LIBS += -framework Foundation -framework SystemConfiguration contains(QT_CONFIG, corewlan) { isEmpty(QMAKE_MAC_SDK)|contains(QMAKE_MAC_SDK, "/Developer/SDKs/MacOSX10.6.sdk") { - LIBS += -framework CoreWLAN + LIBS += -framework CoreWLAN -framework Security DEFINES += MAC_SDK_10_6 } } diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h index 76574a8..5e93193 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.h +++ b/src/plugins/bearer/corewlan/qcorewlanengine.h @@ -78,8 +78,6 @@ public: QNetworkConfigurationPrivatePointer defaultConfiguration(); - bool getWifiInterfaces(); - bool requiresPolling() const; private Q_SLOTS: @@ -95,16 +93,16 @@ private: SCDynamicStoreRef storeSession; CFRunLoopSourceRef runloopSource; - bool hasWifi; protected: - QMap<QString, QMap<QString,QString> > userProfiles; + QMap<QString, QMap<QString,QString> > userProfiles; void startNetworkChangeLoop(); void getUserConfigurations(); QString getNetworkNameFromSsid(const QString &ssid); QString getSsidFromNetworkName(const QString &name); + QStringList foundNetwork(const QString &id, const QString &ssid, const QNetworkConfiguration::StateFlags state, const QString &interfaceName); }; QT_END_NAMESPACE diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 60c6fbd..a366d00 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -50,11 +50,13 @@ #include <QtCore/qstringlist.h> #include <QtCore/qdebug.h> + #include <QDir> #include <CoreWLAN/CoreWLAN.h> #include <CoreWLAN/CWInterface.h> #include <CoreWLAN/CWNetwork.h> #include <CoreWLAN/CWNetwork.h> +#include <CoreWLAN/CW8021XProfile.h> #include <Foundation/NSEnumerator.h> #include <Foundation/NSKeyValueObserving.h> @@ -65,8 +67,6 @@ #include <private/qt_cocoa_helpers_mac_p.h> #include "private/qcore_mac_p.h" -QMap <QString, QString> networkInterfaces; - @interface QNSListener : NSObject { NSNotificationCenter *center; @@ -84,6 +84,8 @@ QMap <QString, QString> networkInterfaces; @end @implementation QNSListener +@synthesize engine; + - (id) init { [locker lock]; @@ -126,12 +128,6 @@ QNSListener *listener = 0; QT_BEGIN_NAMESPACE - -static QString qGetInterfaceType(const QString &interfaceString) -{ - return networkInterfaces.value(interfaceString, QLatin1String("WLAN")); -} - void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info) { for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) { @@ -189,85 +185,147 @@ void QCoreWlanEngine::connectToId(const QString &id) QMacCocoaAutoReleasePool pool; QString interfaceString = getInterfaceFromId(id); - if(networkInterfaces.value(interfaceString) == "WLAN") { - CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; - - if([wifiInterface power]) { - NSError *err = nil; - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; - - NSString *wantedSsid = 0; - bool okToProceed = true; - if(getNetworkNameFromSsid(id) != id) { - NSArray *array = [CW8021XProfile allUser8021XProfiles]; - for (NSUInteger i=0; i<[array count]; ++i) { - const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] userDefinedName]))); - const QString idCheck2 = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] ssid]))); - - if(id == idCheck - || id == idCheck2) { - QString thisName = getSsidFromNetworkName(id); - if(thisName.isEmpty()) { - wantedSsid = qt_mac_QStringToNSString(id); - } else { - wantedSsid = qt_mac_QStringToNSString(thisName); - } - okToProceed = false; - [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile]; - break; - } - } - } + CWInterface *wifiInterface = + [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; - if(okToProceed) { - NSUInteger index = 0; + if ([wifiInterface power]) { + NSError *err = nil; + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; - CWConfiguration *userConfig = [ wifiInterface configuration]; - NSSet *remNets = [userConfig rememberedNetworks]; - NSEnumerator *enumerator = [remNets objectEnumerator]; - CWWirelessProfile *wProfile; + QString wantedSsid; - while ((wProfile = [enumerator nextObject])) { - const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([wProfile ssid]))); + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - if(id == idCheck) { - wantedSsid = [wProfile ssid]; - [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase]; - break; - } - index++; + const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name)); + const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + getNetworkNameFromSsid(ptr->name))); + + bool using8021X = false; + if (idHash2 != id) { + NSArray *array = [CW8021XProfile allUser8021XProfiles]; + + for (NSUInteger i = 0; i < [array count]; ++i) { + const QString networkNameHashCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] userDefinedName]))); + + const QString ssidHash = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] ssid]))); + + if (id == networkNameHashCheck || id == ssidHash) { + const QString thisName = getSsidFromNetworkName(id); + if (thisName.isEmpty()) + wantedSsid = id; + else + wantedSsid = thisName; + + [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile]; + using8021X = true; + break; } } + } - NSDictionary *parametersDict = nil; - NSArray *apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]]; + if (!using8021X) { + QString wantedNetwork; + QMapIterator<QString, QMap<QString,QString> > i(userProfiles); + while (i.hasNext()) { + i.next(); + wantedNetwork = i.key(); + const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork)); + if (id == networkNameHash) { + wantedSsid = getSsidFromNetworkName(wantedNetwork); + break; + } + } + } + NSDictionary *scanParameters = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kCWScanKeyMerge, + [NSNumber numberWithInteger:100], kCWScanKeyRestTime, + qt_mac_QStringToNSString(wantedSsid), kCWScanKeySSID, + nil]; + + NSArray *scanArray = [NSArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:scanParameters error:&err]]; + + if(!err) { + for(uint row=0; row < [scanArray count]; row++ ) { + CWNetwork *apNetwork = [scanArray objectAtIndex:row]; + + if(wantedSsid == qt_mac_NSStringToQString([apNetwork ssid])) { + + if(!using8021X) { + SecKeychainAttribute attributes[3]; + + NSString *account = [apNetwork ssid]; + NSString *keyKind = @"AirPort network password"; + NSString *keyName = account; + + attributes[0].tag = kSecAccountItemAttr; + attributes[0].data = (void *)[account UTF8String]; + attributes[0].length = [account length]; + + attributes[1].tag = kSecDescriptionItemAttr; + attributes[1].data = (void *)[keyKind UTF8String]; + attributes[1].length = [keyKind length]; + + attributes[2].tag = kSecLabelItemAttr; + attributes[2].data = (void *)[keyName UTF8String]; + attributes[2].length = [keyName length]; + + SecKeychainAttributeList attributeList = {3,attributes}; + + SecKeychainSearchRef searchRef; + OSErr result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef); + + NSString *password = @""; + SecKeychainItemRef searchItem; + + if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) { + UInt32 realPasswordLength; + SecKeychainAttribute attributesW[8]; + attributesW[0].tag = kSecAccountItemAttr; + SecKeychainAttributeList listW = {1,attributesW}; + char *realPassword; + OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword); + + if (status == noErr) { + if (realPassword != NULL) { + + QByteArray pBuf; + pBuf.resize(realPasswordLength); + pBuf.prepend(realPassword); + pBuf.insert(realPasswordLength,'\0'); + + password = [NSString stringWithUTF8String:pBuf]; + } + SecKeychainItemFreeContent(&listW, realPassword); + } + + CFRelease(searchItem); + } else { + qDebug() << "SecKeychainSearchCopyNext error"; + } + [params setValue: password forKey: kCWAssocKeyPassphrase]; + } // end using8021X - if(!err) { - for(uint row=0; row < [apArray count]; row++ ) { - CWNetwork *apNetwork = [apArray objectAtIndex:row]; - if([[apNetwork ssid] compare:wantedSsid] == NSOrderedSame) { - bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; + bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; + + if(!err) { if(!result) { emit connectionError(id, ConnectError); } else { return; } + } else { + qDebug() <<"associate ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); } } - } else { - qDebug() <<"ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); - } - - emit connectionError(id, InterfaceLookupError); + } //end scan network } else { - // not wifi + qDebug() <<"scan ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); } - locker.unlock(); emit connectionError(id, InterfaceLookupError); - locker.relock(); } - emit connectionError(id, OperationNotSupported); + + locker.unlock(); + emit connectionError(id, InterfaceLookupError); } void QCoreWlanEngine::disconnectFromId(const QString &id) @@ -275,24 +333,17 @@ void QCoreWlanEngine::disconnectFromId(const QString &id) QMutexLocker locker(&mutex); QString interfaceString = getInterfaceFromId(id); - if(networkInterfaces.value(getInterfaceFromId(id)) == "WLAN") { //wifi only for now -#if defined(MAC_SDK_10_6) - QMacCocoaAutoReleasePool pool; - CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; - [wifiInterface disassociate]; - if([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { - locker.unlock(); - emit connectionError(id, DisconnectionError); - locker.relock(); - } - return; -#endif - } else { + QMacCocoaAutoReleasePool pool; - } + CWInterface *wifiInterface = + [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; - locker.unlock(); - emit connectionError(id, OperationNotSupported); + [wifiInterface disassociate]; + if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { + locker.unlock(); + emit connectionError(id, DisconnectionError); + locker.relock(); + } } void QCoreWlanEngine::requestUpdate() @@ -305,81 +356,15 @@ void QCoreWlanEngine::doRequestUpdate() { QMutexLocker locker(&mutex); - getWifiInterfaces(); + QMacCocoaAutoReleasePool pool; QStringList previous = accessPointConfigurations.keys(); - QMapIterator<QString, QString> i(networkInterfaces); - while (i.hasNext()) { - i.next(); - if (i.value() == QLatin1String("WLAN")) { - QStringList added = scanForSsids(i.key()); - while (!added.isEmpty()) { - previous.removeAll(added.takeFirst()); - } - } - - QNetworkInterface interface = QNetworkInterface::interfaceFromName(i.key()); - - if (!interface.isValid()) - continue; - - uint identifier; - if (interface.index()) - identifier = qHash(QLatin1String("corewlan:") + QString::number(interface.index())); - else - identifier = qHash(QLatin1String("corewlan:") + interface.hardwareAddress()); - - const QString id = QString::number(identifier); - - previous.removeAll(id); - - QString name = interface.humanReadableName(); - if (name.isEmpty()) - name = interface.name(); - - QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; - - if (interface.flags() && QNetworkInterface::IsRunning) - state = QNetworkConfiguration::Defined; - - if (!interface.addressEntries().isEmpty()) - state = QNetworkConfiguration::Active; - - if (accessPointConfigurations.contains(id)) { //handle only scanned AP's - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - bool changed = false; - - ptr->mutex.lock(); - - if (!ptr->isValid) { - ptr->isValid = true; - changed = true; - } - - if (ptr->name != name) { - ptr->name = name; - changed = true; - } - - if (ptr->id != id) { - ptr->id = id; - changed = true; - } - - if (ptr->state != state) { - ptr->state = state; - changed = true; - } - - ptr->mutex.unlock(); - - if (changed) { - locker.unlock(); - emit configurationChanged(ptr); - locker.relock(); - } + NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; + for (uint row = 0; row < [wifiInterfaces count]; ++row) { + foreach (const QString &interface, + scanForSsids(qt_mac_NSStringToQString([wifiInterfaces objectAtIndex:row]))) { + previous.removeAll(interface); } } @@ -413,13 +398,16 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) if([currentInterface power]) { NSError *err = nil; - NSDictionary *parametersDict = nil; + NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kCWScanKeyMerge, + [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType, // get the networks in the scan cache + [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil]; NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err]; CWNetwork *apNetwork; if (!err) { - for(uint row=0; row < [apArray count]; row++ ) { + for(uint row=0; row < [apArray count]; row++ ) { apNetwork = [apArray objectAtIndex:row]; const QString networkSsid = qt_mac_NSStringToQString([apNetwork ssid]); @@ -441,106 +429,109 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) state = QNetworkConfiguration::Undefined; } } + found.append(foundNetwork(id, networkSsid, state, interfaceName)); - if (accessPointConfigurations.contains(id)) { - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - bool changed = false; - - ptr->mutex.lock(); - - if (!ptr->isValid) { - ptr->isValid = true; - changed = true; - } - - if (ptr->name != networkSsid) { - ptr->name = networkSsid; - changed = true; - } - - if (ptr->id != id) { - ptr->id = id; - changed = true; - } - - if (ptr->state != state) { - ptr->state = state; - changed = true; - } - - ptr->mutex.unlock(); - - if (changed) { - locker.unlock(); - emit configurationChanged(ptr); - locker.relock(); - } - addedConfigs << networkSsid; - } else { - QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); - - found.append(id); - ptr->name = networkSsid; - ptr->isValid = true; - ptr->id = id; - ptr->state = state; - ptr->type = QNetworkConfiguration::InternetAccessPoint; - ptr->bearer = QLatin1String("WLAN"); - - accessPointConfigurations.insert(ptr->id, ptr); - configurationInterface.insert(ptr->id, interfaceName); - - locker.unlock(); - emit configurationAdded(ptr); - locker.relock(); - addedConfigs << networkSsid; - } - } - } - } + } //end row + } //end error + } // endwifi power // add known configurations that are not around. QMapIterator<QString, QMap<QString,QString> > i(userProfiles); while (i.hasNext()) { i.next(); + QString networkName = i.key(); - if(!addedConfigs.contains(networkName)) { + const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName)); + + if(!found.contains(id)) { + QString networkSsid = getSsidFromNetworkName(networkName); + const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; QString interfaceName; QMapIterator<QString, QString> ij(i.value()); while (ij.hasNext()) { ij.next(); interfaceName = ij.value(); } - QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); - const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName)); - found.append(id); - - ptr->name = networkName; - ptr->isValid = true; - ptr->id = id; - ptr->bearer = QLatin1String("WLAN"); - ptr->type = QNetworkConfiguration::InternetAccessPoint; - QString ssid = getSsidFromNetworkName(networkName); if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { - if( ssid == qt_mac_NSStringToQString([currentInterface ssid])) { - ptr->state = QNetworkConfiguration::Active; + if( networkSsid == qt_mac_NSStringToQString([currentInterface ssid])) { + state = QNetworkConfiguration::Active; } } - - if(!ptr->state) { - if( addedConfigs.contains(ssid)) { - ptr->state = QNetworkConfiguration::Discovered; + if(state == QNetworkConfiguration::Undefined) { + if( userProfiles.contains(networkName) + && found.contains(ssidId)) { + state = QNetworkConfiguration::Discovered; } } - if(!ptr->state) { - ptr->state = QNetworkConfiguration::Defined; + if(state == QNetworkConfiguration::Undefined) { + state = QNetworkConfiguration::Defined; } - accessPointConfigurations.insert(ptr->id, ptr); - configurationInterface.insert(ptr->id, interfaceName); + + found.append(foundNetwork(id, networkName, state, interfaceName)); + } + } + return found; +} + +QStringList QCoreWlanEngine::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName) +{ + QStringList found; + QMutexLocker locker(&mutex); + if (accessPointConfigurations.contains(id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); + + bool changed = false; + + ptr->mutex.lock(); + + if (!ptr->isValid) { + ptr->isValid = true; + changed = true; + } + + if (ptr->name != name) { + ptr->name = name; + changed = true; + } + + if (ptr->id != id) { + ptr->id = id; + changed = true; + } + + if (ptr->state != state) { + ptr->state = state; + changed = true; + } + + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); } + found.append(id); + } else { + QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); + + ptr->name = name; + ptr->isValid = true; + ptr->id = id; + ptr->state = state; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->bearer = QLatin1String("WLAN"); + + accessPointConfigurations.insert(ptr->id, ptr); + configurationInterface.insert(ptr->id, interfaceName); + + locker.unlock(); + emit configurationAdded(ptr); + locker.relock(); + found.append(id); } return found; } @@ -573,20 +564,6 @@ bool QCoreWlanEngine::isKnownSsid(const QString &ssid) return false; } -bool QCoreWlanEngine::getWifiInterfaces() -{ - QMutexLocker locker(&mutex); - - networkInterfaces.clear(); - QMacCocoaAutoReleasePool pool; - - NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; - for(uint row=0; row < [wifiInterfaces count]; row++ ) { - networkInterfaces.insert( qt_mac_NSStringToQString([wifiInterfaces objectAtIndex:row]),"WLAN"); - } - return true; -} - QNetworkSession::State QCoreWlanEngine::sessionStateForId(const QString &id) { QMutexLocker locker(&mutex); @@ -692,16 +669,15 @@ QString QCoreWlanEngine::getSsidFromNetworkName(const QString &name) QMapIterator<QString, QMap<QString,QString> > i(userProfiles); while (i.hasNext()) { i.next(); - QMap<QString,QString> map = i.value(); QMapIterator<QString, QString> ij(i.value()); while (ij.hasNext()) { ij.next(); - const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") +i.key())); - if(name == i.key() || name == idCheck) { + const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key())); + if(name == i.key() || name == networkNameHash) { return ij.key(); } - } + } } return QString(); } @@ -718,9 +694,7 @@ QString QCoreWlanEngine::getNetworkNameFromSsid(const QString &ssid) if(ij.key() == ssid) { return i.key(); } - } - return map.key(ssid); } return QString(); } @@ -735,10 +709,10 @@ void QCoreWlanEngine::getUserConfigurations() for(uint row=0; row < [wifiInterfaces count]; row++ ) { CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]]; - + NSString *nsInterfaceName = [wifiInterface name]; // add user configured system networks SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil); - CFDictionaryRef airportPlist = (const __CFDictionary*)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", [wifiInterface name]]); + NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]); CFRelease(dynRef); NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"]; @@ -748,7 +722,7 @@ void QCoreWlanEngine::getUserConfigurations() QString thisSsid = qt_mac_NSStringToQString(ssidkey); if(!userProfiles.contains(thisSsid)) { QMap <QString,QString> map; - map.insert(thisSsid, qt_mac_NSStringToQString([wifiInterface name])); + map.insert(thisSsid, qt_mac_NSStringToQString(nsInterfaceName)); userProfiles.insert(thisSsid, map); } } @@ -782,7 +756,7 @@ void QCoreWlanEngine::getUserConfigurations() if(!userProfiles.contains(networkName) && !ssid.isEmpty()) { QMap<QString,QString> map; - map.insert(ssid, qt_mac_NSStringToQString([wifiInterface name])); + map.insert(ssid, qt_mac_NSStringToQString(nsInterfaceName)); userProfiles.insert(networkName, map); } } diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp index dfc74f2..d65025b 100644 --- a/src/plugins/bearer/generic/qgenericengine.cpp +++ b/src/plugins/bearer/generic/qgenericengine.cpp @@ -66,6 +66,7 @@ QT_BEGIN_NAMESPACE +#ifndef QT_NO_NETWORKINTERFACE static QString qGetInterfaceType(const QString &interface) { #ifdef Q_OS_WIN32 @@ -139,6 +140,7 @@ static QString qGetInterfaceType(const QString &interface) return QLatin1String("Unknown"); } +#endif QGenericEngine::QGenericEngine(QObject *parent) : QBearerEngineImpl(parent) @@ -180,6 +182,7 @@ void QGenericEngine::requestUpdate() void QGenericEngine::doRequestUpdate() { +#ifndef QT_NO_NETWORKINTERFACE QMutexLocker locker(&mutex); // Immediately after connecting with a wireless access point @@ -203,7 +206,7 @@ void QGenericEngine::doRequestUpdate() if (interface.flags() & QNetworkInterface::IsLoopBack) continue; - // ignore WLAN interface handled in seperate engine + // ignore WLAN interface handled in separate engine if (qGetInterfaceType(interface.name()) == QLatin1String("WLAN")) continue; @@ -221,8 +224,8 @@ void QGenericEngine::doRequestUpdate() if (name.isEmpty()) name = interface.name(); - QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Discovered; - if (interface.flags() & QNetworkInterface::IsUp) + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined; + if((interface.flags() & QNetworkInterface::IsUp) && !interface.addressEntries().isEmpty()) state |= QNetworkConfiguration::Active; if (accessPointConfigurations.contains(id)) { @@ -290,6 +293,8 @@ void QGenericEngine::doRequestUpdate() } locker.unlock(); +#endif + emit updateCompleted(); } diff --git a/src/plugins/bearer/icd/icd.pro b/src/plugins/bearer/icd/icd.pro index 5eaf5af..f411de2 100644 --- a/src/plugins/bearer/icd/icd.pro +++ b/src/plugins/bearer/icd/icd.pro @@ -3,8 +3,8 @@ include(../../qpluginbase.pri) QT += network dbus -CONFIG += link_pkgconfig -PKGCONFIG += glib-2.0 dbus-glib-1 gconf-2.0 osso-ic conninet +QMAKE_CXXFLAGS += $$QT_CFLAGS_ICD +LIBS += $$QT_LIBS_ICD HEADERS += qicdengine.h \ monitor.h \ diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp index 5e9dc0a..7a4cb9d 100644 --- a/src/plugins/bearer/icd/qicdengine.cpp +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -335,7 +335,7 @@ void QIcdEngine::doRequestUpdate() locker.relock(); } - if (!ap.scan.network_type.startsWith("WLAN")) + if (!ap.scan.network_type.startsWith(QLatin1String("WLAN"))) continue; // not a wlan AP } } else { @@ -417,7 +417,8 @@ QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const { return QNetworkConfigurationManager::CanStartAndStopInterfaces | QNetworkConfigurationManager::DataStatistics | - QNetworkConfigurationManager::ForcedRoaming; + QNetworkConfigurationManager::ForcedRoaming | + QNetworkConfigurationManager::NetworkSessionRequired; } QNetworkSessionPrivate *QIcdEngine::createSessionBackend() diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp index a2ae65c..5bf95dc 100644 --- a/src/plugins/bearer/icd/qnetworksession_impl.cpp +++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp @@ -391,7 +391,7 @@ quint64 QNetworkSessionPrivateImpl::getStatistics(bool sent) const return 0; } - foreach (Maemo::IcdStatisticsResult res, stats_results) { + foreach (const Maemo::IcdStatisticsResult &res, stats_results) { if (res.params.network_attrs & ICD_NW_ATTR_IAPNAME) { /* network_id is the IAP UUID */ if (QString(res.params.network_id.data()) == activeConfig.identifier()) { @@ -1110,7 +1110,7 @@ void QNetworkSessionPrivateImpl::reject() { } - +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const { if (!publicConfig.isValid() || state != QNetworkSession::Connected) @@ -1121,7 +1121,7 @@ QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const return QNetworkInterface::interfaceFromName(currentNetworkInterface); } - +#endif void QNetworkSessionPrivateImpl::setSessionProperty(const QString& key, const QVariant& value) { diff --git a/src/plugins/bearer/icd/qnetworksession_impl.h b/src/plugins/bearer/icd/qnetworksession_impl.h index 587e6dc..c02faac 100644 --- a/src/plugins/bearer/icd/qnetworksession_impl.h +++ b/src/plugins/bearer/icd/qnetworksession_impl.h @@ -56,11 +56,6 @@ #include <QtNetwork/private/qnetworksession_p.h> #include <QtNetwork/qnetworkconfigmanager.h> -//#include "qnetworkconfigmanager_maemo_p.h" -//#include "qnetworksession.h" - -//#include <qnetworksession.h> -//#include <QNetworkInterface> #include <QtCore/qdatetime.h> #include <icd/dbus_api.h> @@ -90,7 +85,9 @@ public: //notification hooks to discover future state changes. void syncStateWithInterface(); +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface currentInterface() const; +#endif QVariant sessionProperty(const QString& key) const; void setSessionProperty(const QString& key, const QVariant& value); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index d7e315a..28ee38e 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -91,6 +91,15 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) connect(userSettings, SIGNAL(newConnection(QDBusObjectPath)), this, SLOT(newConnection(QDBusObjectPath))); + QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); +} + +QNetworkManagerEngine::~QNetworkManagerEngine() +{ +} + +void QNetworkManagerEngine::init() +{ // Get current list of access points. foreach (const QDBusObjectPath &devicePath, interface->getDevices()) deviceAdded(devicePath); @@ -113,10 +122,6 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) } } -QNetworkManagerEngine::~QNetworkManagerEngine() -{ -} - bool QNetworkManagerEngine::networkManagerAvailable() const { QMutexLocker locker(&mutex); @@ -146,7 +151,7 @@ QString QNetworkManagerEngine::getInterfaceFromId(const QString &id) continue; QNetworkManagerInterfaceDevice device(devices.at(0).path()); - return device.networkInterface().name(); + return device.networkInterface(); } } diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index 05a1429..af3f450 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -70,6 +70,8 @@ public: QNetworkManagerEngine(QObject *parent = 0); ~QNetworkManagerEngine(); + Q_INVOKABLE void init(); + bool networkManagerAvailable() const; QString getInterfaceFromId(const QString &id); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index d23bb0d..a20370b 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -353,9 +353,9 @@ QString QNetworkManagerInterfaceDevice::udi() const return d->connectionInterface->property("Udi").toString(); } -QNetworkInterface QNetworkManagerInterfaceDevice::networkInterface() const +QString QNetworkManagerInterfaceDevice::networkInterface() const { - return QNetworkInterface::interfaceFromName(d->connectionInterface->property("Interface").toString()); + return d->connectionInterface->property("Interface").toString(); } quint32 QNetworkManagerInterfaceDevice::ip4Address() const diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 048f628..95f5b4a 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -59,8 +59,6 @@ #include <QtDBus/QDBusInterface> #include <QtDBus/QDBusMessage> #include <QtDBus/QDBusReply> -#include <QNetworkInterface> - #include <QtDBus/QDBusPendingCallWatcher> #include <QtDBus/QDBusObjectPath> @@ -215,7 +213,7 @@ public: Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag); - QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0); + explicit QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0); ~QNetworkManagerInterfaceAccessPoint(); QDBusInterface *connectionInterface() const; @@ -248,11 +246,11 @@ class QNetworkManagerInterfaceDevice : public QObject public: - QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = 0); + explicit QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = 0); ~QNetworkManagerInterfaceDevice(); QString udi() const; - QNetworkInterface networkInterface() const; + QString networkInterface() const; QDBusInterface *connectionInterface() const; quint32 ip4Address() const; quint32 state() const; @@ -277,7 +275,8 @@ class QNetworkManagerInterfaceDeviceWired : public QObject public: - QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent = 0); + explicit QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, + QObject *parent = 0); ~QNetworkManagerInterfaceDeviceWired(); QDBusInterface *connectionInterface() const; @@ -311,7 +310,8 @@ public: Rsn = 0x20 }; - QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent = 0); + explicit QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, + QObject *parent = 0); ~QNetworkManagerInterfaceDeviceWireless(); QDBusObjectPath path() const; @@ -342,7 +342,7 @@ class QNetworkManagerSettings : public QObject public: - QNetworkManagerSettings(const QString &settingsService, QObject *parent = 0); + explicit QNetworkManagerSettings(const QString &settingsService, QObject *parent = 0); ~QNetworkManagerSettings(); QDBusInterface *connectionInterface() const; @@ -402,7 +402,7 @@ public: Activated = 2 }; - QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = 0); + explicit QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = 0); ~ QNetworkManagerConnectionActive(); QDBusInterface *connectionInterface() const; @@ -430,7 +430,7 @@ class QNetworkManagerIp4Config : public QObject Q_OBJECT public: - QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0); + explicit QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0); ~QNetworkManagerIp4Config(); QStringList domains() const; diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index db1759c..33cce69 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -49,8 +49,6 @@ #include <QtCore/qdebug.h> #include <QtCore/qmutex.h> -#include <QtNetwork/qnetworkinterface.h> - QT_BEGIN_NAMESPACE static QBearerEngineImpl *getEngineFromId(const QString &id) @@ -218,6 +216,7 @@ void QNetworkSessionPrivateImpl::reject() { } +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const { if (!publicConfig.isValid() || !engine || state != QNetworkSession::Connected) @@ -229,6 +228,7 @@ QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const return QNetworkInterface(); return QNetworkInterface::interfaceFromName(interface); } +#endif QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString &key) const { diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index c644174..3becbf0 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -83,7 +83,9 @@ public: //notification hooks to discover future state changes. void syncStateWithInterface(); +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface currentInterface() const; +#endif QVariant sessionProperty(const QString& key) const; void setSessionProperty(const QString& key, const QVariant& value); diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp index 0737942..512ea51 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -152,6 +152,7 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() } } +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface QNetworkSessionPrivateImpl::interface(TUint iapId) const { QString interfaceName; @@ -189,7 +190,9 @@ QNetworkInterface QNetworkSessionPrivateImpl::interface(TUint iapId) const return QNetworkInterface::interfaceFromName(interfaceName); } +#endif +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const { if (!publicConfig.isValid() || state != QNetworkSession::Connected) { @@ -198,6 +201,7 @@ QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const return activeInterface; } +#endif QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const { @@ -241,15 +245,24 @@ void QNetworkSessionPrivateImpl::open() // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring iConnectionMonitor.CancelNotifications(); - // Configuration must be at least in Discovered - state for connecting purposes. - if ((publicConfig.state() & QNetworkConfiguration::Discovered) != - QNetworkConfiguration::Discovered) { + // Configuration may have been invalidated after session creation by platform + // (e.g. configuration has been deleted). + if (!publicConfig.isValid()) { newState(QNetworkSession::Invalid); iError = QNetworkSession::InvalidConfigurationError; emit QNetworkSessionPrivate::error(iError); syncStateWithInterface(); return; } + // If opening a (un)defined configuration, session emits error and enters + // NotAvailable -state. + if (publicConfig.state() == QNetworkConfiguration::Undefined || + publicConfig.state() == QNetworkConfiguration::Defined) { + newState(QNetworkSession::NotAvailable); + iError = QNetworkSession::InvalidConfigurationError; + emit QNetworkSessionPrivate::error(iError); + return; + } TInt error = iSocketServ.Connect(); if (error != KErrNone) { @@ -300,7 +313,9 @@ void QNetworkSessionPrivateImpl::open() if (connInfo().iIapId == symbianConfig->numericId) { if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) { activeConfig = publicConfig; +#ifndef QT_NO_NETWORKINTERFACE activeInterface = interface(symbianConfig->numericId); +#endif connected = ETrue; startTime = QDateTime::currentDateTime(); if (iDynamicSetdefaultif) { @@ -450,15 +465,49 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals) void QNetworkSessionPrivateImpl::stop() { - if (!isOpen) { - return; + if (!isOpen && + publicConfig.isValid() && + publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { + // If the publicConfig is type of IAP, enumerate through connections at + // connection monitor. If publicConfig is active in that list, stop it. + // Otherwise there is nothing to stop. Note: because this QNetworkSession is not open, + // activeConfig is not usable. + TUint count; + TRequestStatus status; + iConnectionMonitor.GetConnectionCount(count, status); + User::WaitForRequest(status); + if (status.Int() != KErrNone) { + return; + } + TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f + TUint connectionId; + for (TInt i = 1; i <= count; ++i) { + // Get (connection monitor's assigned) connection ID + TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections); + if (ret == KErrNone) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + QMutexLocker configLocker(&symbianConfig->mutex); + + // See if connection Id matches with our Id. If so, stop() it. + if (symbianConfig->connectionId == connectionId) { + ret = iConnectionMonitor.SetBoolAttribute(connectionId, + 0, // subConnectionId don't care + KConnectionStop, + ETrue); + } + } + } + } else if (isOpen) { + // Since we are open, use RConnection to stop the interface + isOpen = false; + newState(QNetworkSession::Closing); + iConnection.Stop(RConnection::EStopAuthoritative); + isOpen = true; + close(false); + emit closed(); } - isOpen = false; - newState(QNetworkSession::Closing); - iConnection.Stop(RConnection::EStopAuthoritative); - isOpen = true; - close(false); - emit closed(); } void QNetworkSessionPrivateImpl::migrate() @@ -794,7 +843,7 @@ void QNetworkSessionPrivateImpl::RunL() TInt statusCode = iStatus.Int(); switch (statusCode) { - case KErrNone: // Connection created succesfully + case KErrNone: // Connection created successfully { TInt error = KErrNone; QNetworkConfiguration newActiveConfig = activeConfiguration(); @@ -835,7 +884,9 @@ void QNetworkSessionPrivateImpl::RunL() toSymbianConfig(privateConfiguration(activeConfig)); symbianConfig->mutex.lock(); +#ifndef QT_NO_NETWORKINTERFACE activeInterface = interface(symbianConfig->numericId); +#endif if (publicConfig.type() == QNetworkConfiguration::UserChoice) { serviceConfig = QNetworkConfigurationManager() .configurationFromIdentifier(symbianConfig->serviceNetworkPtr->id); @@ -893,9 +944,11 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(privateConfiguration(activeConfig)); +#ifndef QT_NO_NETWORKINTERFACE symbianConfig->mutex.lock(); activeInterface = interface(symbianConfig->numericId); symbianConfig->mutex.unlock(); +#endif #ifdef SNAP_FUNCTIONALITY_AVAILABLE if (iDynamicSetdefaultif) { diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h index 98d4222..9a57eae 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.h +++ b/src/plugins/bearer/symbian/qnetworksession_impl.h @@ -72,12 +72,11 @@ QT_BEGIN_NAMESPACE class ConnectionProgressNotifier; class SymbianEngine; +class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, #ifdef SNAP_FUNCTIONALITY_AVAILABLE -class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, public MMobilityProtocolResp, - public MConnectionMonitorObserver -#else -class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive, public MConnectionMonitorObserver + public MMobilityProtocolResp, #endif + public MConnectionMonitorObserver { Q_OBJECT public: @@ -90,7 +89,9 @@ public: //notification hooks to discover future state changes. void syncStateWithInterface(); +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface currentInterface() const; +#endif QVariant sessionProperty(const QString& key) const; void setSessionProperty(const QString& key, const QVariant& value); @@ -138,12 +139,16 @@ private: void handleSymbianConnectionStatusChange(TInt aConnectionStatus, TInt aError, TUint accessPointId = 0); QNetworkConfiguration bestConfigFromSNAP(const QNetworkConfiguration& snapConfig) const; QNetworkConfiguration activeConfiguration(TUint32 iapId = 0) const; +#ifndef QT_NO_NETWORKINTERFACE QNetworkInterface interface(TUint iapId) const; +#endif private: // data SymbianEngine *engine; +#ifndef QT_NO_NETWORKINTERFACE mutable QNetworkInterface activeInterface; +#endif QDateTime startTime; diff --git a/src/plugins/bearer/symbian/symbian.pro b/src/plugins/bearer/symbian/symbian.pro index 9613def..f915570 100644 --- a/src/plugins/bearer/symbian/symbian.pro +++ b/src/plugins/bearer/symbian/symbian.pro @@ -10,14 +10,16 @@ SOURCES += symbianengine.cpp \ qnetworksession_impl.cpp \ main.cpp -exists($${EPOCROOT}epoc32/release/winscw/udeb/cmmanager.lib)| \ -exists($${EPOCROOT}epoc32/release/armv5/lib/cmmanager.lib) { - message("Building with SNAP support") - DEFINES += SNAP_FUNCTIONALITY_AVAILABLE - LIBS += -lcmmanager -} else { - message("Building without SNAP support") - LIBS += -lapengine +symbian { + exists($${EPOCROOT}epoc32/release/winscw/udeb/cmmanager.lib)| \ + exists($${EPOCROOT}epoc32/release/armv5/lib/cmmanager.lib) { + message("Building with SNAP support") + DEFINES += SNAP_FUNCTIONALITY_AVAILABLE + LIBS += -lcmmanager + } else { + message("Building without SNAP support") + LIBS += -lapengine + } } INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index 980892a..440f463 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -45,6 +45,16 @@ #include <commdb.h> #include <cdbcols.h> #include <d32dbms.h> +#include <QEventLoop> +#include <QTimer> +#include <QTime> // For randgen seeding +#include <QtCore> // For randgen seeding + +// #define QT_BEARERMGMT_CONFIGMGR_DEBUG + +#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG +#include <QDebug> +#endif #ifdef SNAP_FUNCTIONALITY_AVAILABLE #include <cmdestination.h> @@ -100,10 +110,15 @@ QString SymbianNetworkConfigurationPrivate::bearerName() const } SymbianEngine::SymbianEngine(QObject *parent) -: QBearerEngine(parent), CActive(CActive::EPriorityIdle), iFirstUpdate(true), iInitOk(true) +: QBearerEngine(parent), CActive(CActive::EPriorityIdle), iFirstUpdate(true), iInitOk(true), + iIgnoringUpdates(false), iTimeToWait(0), iIgnoreEventLoop(0) { CActiveScheduler::Add(this); + // Seed the randomgenerator + qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid()); + iIgnoreEventLoop = new QEventLoop(this); + TRAPD(error, ipCommsDB = CCommsDatabase::NewL(EDatabaseTypeIAP)); if (error != KErrNone) { iInitOk = false; @@ -138,9 +153,7 @@ SymbianEngine::SymbianEngine(QObject *parent) updateConfigurations(); updateStatesToSnaps(); - updateAvailableAccessPoints(); // On first time updates synchronously (without WLAN scans) - // Start monitoring IAP and/or SNAP changes in Symbian CommsDB startCommsDatabaseNotifications(); iFirstUpdate = false; @@ -184,7 +197,8 @@ QNetworkConfigurationManager::Capabilities SymbianEngine::capabilities() const capFlags = QNetworkConfigurationManager::CanStartAndStopInterfaces | QNetworkConfigurationManager::DirectConnectionRouting | QNetworkConfigurationManager::SystemSessionSupport | - QNetworkConfigurationManager::DataStatistics; + QNetworkConfigurationManager::DataStatistics | + QNetworkConfigurationManager::NetworkSessionRequired; #ifdef SNAP_FUNCTIONALITY_AVAILABLE capFlags |= QNetworkConfigurationManager::ApplicationLevelRoaming | @@ -230,7 +244,7 @@ void SymbianEngine::updateConfigurationsL() QList<QString> knownConfigs = accessPointConfigurations.keys(); QList<QString> knownSnapConfigs = snapConfigurations.keys(); - + #ifdef SNAP_FUNCTIONALITY_AVAILABLE // S60 version is >= Series60 3rd Edition Feature Pack 2 TInt error = KErrNone; @@ -737,8 +751,7 @@ void SymbianEngine::updateStatesToSnaps() QMutexLocker locker(&mutex); // Go through SNAPs and set correct state to SNAPs - QList<QString> snapConfigIdents = snapConfigurations.keys(); - foreach (QString iface, snapConfigIdents) { + foreach (const QString &iface, snapConfigurations.keys()) { bool discovered = false; bool active = false; QNetworkConfigurationPrivatePointer ptr = snapConfigurations.value(iface); @@ -873,6 +886,13 @@ void SymbianEngine::RunL() { QMutexLocker locker(&mutex); + if (iIgnoringUpdates) { +#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG + qDebug("CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently)."); +#endif + return; + } + if (iStatus != KErrCancel) { RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); switch (event) { @@ -880,16 +900,32 @@ void SymbianEngine::RunL() case RDbNotifier::ECommit: /** A transaction has been committed. */ case RDbNotifier::ERollback: /** A transaction has been rolled back */ case RDbNotifier::ERecover: /** The database has been recovered */ - // Note that if further database events occur while a client is handling - // a request completion, the notifier records the most significant database - // event and this is signalled as soon as the client issues the next - // RequestNotification() request. - // => Stop recording notifications - stopCommsDatabaseNotifications(); - TRAPD(error, updateConfigurationsL()); - if (error == KErrNone) { - updateStatesToSnaps(); +#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG + qDebug("CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); +#endif + iIgnoringUpdates = true; + // Other events than ECommit get lower priority. In practice with those events, + // we delay_before_updating methods, whereas + // with ECommit we _update_before_delaying the reaction to next event. + // Few important notes: 1) listening to only ECommit does not seem to be adequate, + // but updates will be missed. Hence other events are reacted upon too. + // 2) RDbNotifier records the most significant event, and that will be returned once + // we issue new RequestNotification, and hence updates will not be missed even + // when we are 'not reacting to them' for few seconds. + if (event == RDbNotifier::ECommit) { + TRAPD(error, updateConfigurationsL()); + if (error == KErrNone) { + updateStatesToSnaps(); + } + waitRandomTime(); + } else { + waitRandomTime(); + TRAPD(error, updateConfigurationsL()); + if (error == KErrNone) { + updateStatesToSnaps(); + } } + iIgnoringUpdates = false; // Wait time done, allow updating again iWaitingCommsDatabaseNotifications = true; break; default: @@ -1014,6 +1050,20 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) } } +// Waits for 1..4 seconds. +void SymbianEngine::waitRandomTime() +{ + iTimeToWait = (qAbs(qrand()) % 5) * 1000; + if (iTimeToWait < 1000) { + iTimeToWait = 1000; + } +#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG + qDebug("QNetworkConfigurationManager waiting random time: %d ms", iTimeToWait); +#endif + QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit())); + iIgnoreEventLoop->exec(); +} + QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId) { QMutexLocker locker(&mutex); diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h index e6af908..2e7ae60 100644 --- a/src/plugins/bearer/symbian/symbianengine.h +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -53,6 +53,7 @@ #endif class CCommsDatabase; +class QEventLoop; QT_BEGIN_NAMESPACE class QTimer; @@ -148,6 +149,7 @@ private: void accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo); void startCommsDatabaseNotifications(); void stopCommsDatabaseNotifications(); + void waitRandomTime(); QNetworkConfigurationPrivatePointer defaultConfigurationL(); TBool GetS60PlatformVersion(TUint& aMajor, TUint& aMinor) const; @@ -170,8 +172,10 @@ private: // Data TBool iOnline; TBool iInitOk; TBool iUpdateGoingOn; + TBool iIgnoringUpdates; + TUint iTimeToWait; + QEventLoop* iIgnoreEventLoop; - AccessPointsAvailabilityScanner* ipAccessPointsAvailabilityScanner; friend class QNetworkSessionPrivate; diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index abe3ffe..93b7cc6 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -183,82 +183,34 @@ inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device) } -static bool read_jpeg_size(QIODevice *device, int &w, int &h) +inline static bool read_jpeg_size(int &w, int &h, j_decompress_ptr cinfo) { - bool rt = false; - struct jpeg_decompress_struct cinfo; + (void) jpeg_calc_output_dimensions(cinfo); - struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); - struct my_error_mgr jerr; - - jpeg_create_decompress(&cinfo); - - cinfo.src = iod_src; - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = my_error_exit; - - if (!setjmp(jerr.setjmp_buffer)) { -#if defined(Q_OS_UNIXWARE) - (void) jpeg_read_header(&cinfo, B_TRUE); -#else - (void) jpeg_read_header(&cinfo, true); -#endif - (void) jpeg_calc_output_dimensions(&cinfo); - - w = cinfo.output_width; - h = cinfo.output_height; - rt = true; - } - jpeg_destroy_decompress(&cinfo); - delete iod_src; - return rt; + w = cinfo->output_width; + h = cinfo->output_height; + return true; } #define HIGH_QUALITY_THRESHOLD 50 -static bool read_jpeg_format(QIODevice *device, QImage::Format &format) +inline static bool read_jpeg_format(QImage::Format &format, j_decompress_ptr cinfo) { - bool result = false; - struct jpeg_decompress_struct cinfo; - - struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); - struct my_error_mgr jerr; - - jpeg_create_decompress(&cinfo); - - cinfo.src = iod_src; - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = my_error_exit; - if (!setjmp(jerr.setjmp_buffer)) { -#if defined(Q_OS_UNIXWARE) - (void) jpeg_read_header(&cinfo, B_TRUE); -#else - (void) jpeg_read_header(&cinfo, true); -#endif - // This does not allocate memory for the whole image - // or such, so we are safe. - (void) jpeg_start_decompress(&cinfo); - result = true; - switch (cinfo.output_components) { - case 1: - format = QImage::Format_Indexed8; - break; - case 3: - case 4: - format = QImage::Format_RGB32; - break; - default: - result = false; - break; - } - cinfo.output_scanline = cinfo.output_height; - (void) jpeg_finish_decompress(&cinfo); + bool result = true; + switch (cinfo->output_components) { + case 1: + format = QImage::Format_Indexed8; + break; + case 3: + case 4: + format = QImage::Format_RGB32; + break; + default: + result = false; + break; } - jpeg_destroy_decompress(&cinfo); - delete iod_src; + cinfo->output_scanline = cinfo->output_height; return result; } @@ -291,29 +243,11 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, return !dest->isNull(); } -static bool read_jpeg_image(QIODevice *device, QImage *outImage, +static bool read_jpeg_image(QImage *outImage, QSize scaledSize, QRect scaledClipRect, - QRect clipRect, int inQuality ) + QRect clipRect, int inQuality, j_decompress_ptr info, struct my_error_mgr* err ) { - struct jpeg_decompress_struct cinfo; - - struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); - struct my_error_mgr jerr; - - jpeg_create_decompress(&cinfo); - - cinfo.src = iod_src; - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = my_error_exit; - - if (!setjmp(jerr.setjmp_buffer)) { -#if defined(Q_OS_UNIXWARE) - (void) jpeg_read_header(&cinfo, B_TRUE); -#else - (void) jpeg_read_header(&cinfo, true); -#endif - + if (!setjmp(err->setjmp_buffer)) { // -1 means default quality. int quality = inQuality; if (quality < 0) @@ -335,16 +269,16 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, } else if (clipRect.isEmpty()) { // No clipping, but scaling: if we can map back to an // integer pixel boundary, then clip before scaling. - if ((cinfo.image_width % scaledSize.width()) == 0 && - (cinfo.image_height % scaledSize.height()) == 0) { - int x = scaledClipRect.x() * cinfo.image_width / + if ((info->image_width % scaledSize.width()) == 0 && + (info->image_height % scaledSize.height()) == 0) { + int x = scaledClipRect.x() * info->image_width / scaledSize.width(); - int y = scaledClipRect.y() * cinfo.image_height / + int y = scaledClipRect.y() * info->image_height / scaledSize.height(); int width = (scaledClipRect.right() + 1) * - cinfo.image_width / scaledSize.width() - x; + info->image_width / scaledSize.width() - x; int height = (scaledClipRect.bottom() + 1) * - cinfo.image_height / scaledSize.height() - y; + info->image_height / scaledSize.height() - y; clipRect = QRect(x, y, width, height); scaledSize = scaledClipRect.size(); scaledClipRect = QRect(); @@ -358,69 +292,69 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, // Determine the scale factor to pass to libjpeg for quick downscaling. if (!scaledSize.isEmpty()) { if (clipRect.isEmpty()) { - cinfo.scale_denom = - qMin(cinfo.image_width / scaledSize.width(), - cinfo.image_height / scaledSize.height()); + info->scale_denom = + qMin(info->image_width / scaledSize.width(), + info->image_height / scaledSize.height()); } else { - cinfo.scale_denom = + info->scale_denom = qMin(clipRect.width() / scaledSize.width(), clipRect.height() / scaledSize.height()); } - if (cinfo.scale_denom < 2) { - cinfo.scale_denom = 1; - } else if (cinfo.scale_denom < 4) { - cinfo.scale_denom = 2; - } else if (cinfo.scale_denom < 8) { - cinfo.scale_denom = 4; + if (info->scale_denom < 2) { + info->scale_denom = 1; + } else if (info->scale_denom < 4) { + info->scale_denom = 2; + } else if (info->scale_denom < 8) { + info->scale_denom = 4; } else { - cinfo.scale_denom = 8; + info->scale_denom = 8; } - cinfo.scale_num = 1; + info->scale_num = 1; if (!clipRect.isEmpty()) { // Correct the scale factor so that we clip accurately. // It is recommended that the clip rectangle be aligned // on an 8-pixel boundary for best performance. - while (cinfo.scale_denom > 1 && - ((clipRect.x() % cinfo.scale_denom) != 0 || - (clipRect.y() % cinfo.scale_denom) != 0 || - (clipRect.width() % cinfo.scale_denom) != 0 || - (clipRect.height() % cinfo.scale_denom) != 0)) { - cinfo.scale_denom /= 2; + while (info->scale_denom > 1 && + ((clipRect.x() % info->scale_denom) != 0 || + (clipRect.y() % info->scale_denom) != 0 || + (clipRect.width() % info->scale_denom) != 0 || + (clipRect.height() % info->scale_denom) != 0)) { + info->scale_denom /= 2; } } } // If high quality not required, use fast decompression if( quality < HIGH_QUALITY_THRESHOLD ) { - cinfo.dct_method = JDCT_IFAST; - cinfo.do_fancy_upsampling = FALSE; + info->dct_method = JDCT_IFAST; + info->do_fancy_upsampling = FALSE; } - (void) jpeg_calc_output_dimensions(&cinfo); + (void) jpeg_calc_output_dimensions(info); // Determine the clip region to extract. - QRect imageRect(0, 0, cinfo.output_width, cinfo.output_height); + QRect imageRect(0, 0, info->output_width, info->output_height); QRect clip; if (clipRect.isEmpty()) { clip = imageRect; - } else if (cinfo.scale_denom == cinfo.scale_num) { + } else if (info->scale_denom == info->scale_num) { clip = clipRect.intersected(imageRect); } else { // The scale factor was corrected above to ensure that // we don't miss pixels when we scale the clip rectangle. - clip = QRect(clipRect.x() / int(cinfo.scale_denom), - clipRect.y() / int(cinfo.scale_denom), - clipRect.width() / int(cinfo.scale_denom), - clipRect.height() / int(cinfo.scale_denom)); + clip = QRect(clipRect.x() / int(info->scale_denom), + clipRect.y() / int(info->scale_denom), + clipRect.width() / int(info->scale_denom), + clipRect.height() / int(info->scale_denom)); clip = clip.intersected(imageRect); } // Allocate memory for the clipped QImage. - if (!ensureValidImage(outImage, &cinfo, clip.size())) - longjmp(jerr.setjmp_buffer, 1); + if (!ensureValidImage(outImage, info, clip.size())) + longjmp(err->setjmp_buffer, 1); // Avoid memcpy() overhead if grayscale with no clipping. - bool quickGray = (cinfo.output_components == 1 && + bool quickGray = (info->output_components == 1 && clip == imageRect); if (!quickGray) { // Ask the jpeg library to allocate a temporary row. @@ -429,23 +363,23 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, // jpeg_start_decompress(). We can't use "new" here // because we are inside the setjmp() block and an error // in the jpeg input stream would cause a memory leak. - JSAMPARRAY rows = (cinfo.mem->alloc_sarray) - ((j_common_ptr)&cinfo, JPOOL_IMAGE, - cinfo.output_width * cinfo.output_components, 1); + JSAMPARRAY rows = (info->mem->alloc_sarray) + ((j_common_ptr)info, JPOOL_IMAGE, + info->output_width * info->output_components, 1); - (void) jpeg_start_decompress(&cinfo); + (void) jpeg_start_decompress(info); - while (cinfo.output_scanline < cinfo.output_height) { - int y = int(cinfo.output_scanline) - clip.y(); + while (info->output_scanline < info->output_height) { + int y = int(info->output_scanline) - clip.y(); if (y >= clip.height()) break; // We've read the entire clip region, so abort. - (void) jpeg_read_scanlines(&cinfo, rows, 1); + (void) jpeg_read_scanlines(info, rows, 1); if (y < 0) continue; // Haven't reached the starting line yet. - if (cinfo.output_components == 3) { + if (info->output_components == 3) { // Expand 24->32 bpp. uchar *in = rows[0] + clip.x() * 3; QRgb *out = (QRgb*)outImage->scanLine(y); @@ -453,7 +387,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, *out++ = qRgb(in[0], in[1], in[2]); in += 3; } - } else if (cinfo.out_color_space == JCS_CMYK) { + } else if (info->out_color_space == JCS_CMYK) { // Convert CMYK->RGB. uchar *in = rows[0] + clip.x() * 4; QRgb *out = (QRgb*)outImage->scanLine(y); @@ -463,7 +397,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, k * in[2] / 255); in += 4; } - } else if (cinfo.output_components == 1) { + } else if (info->output_components == 1) { // Grayscale. memcpy(outImage->scanLine(y), rows[0] + clip.x(), clip.width()); @@ -471,37 +405,36 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, } } else { // Load unclipped grayscale data directly into the QImage. - (void) jpeg_start_decompress(&cinfo); - while (cinfo.output_scanline < cinfo.output_height) { - uchar *row = outImage->scanLine(cinfo.output_scanline); - (void) jpeg_read_scanlines(&cinfo, &row, 1); + (void) jpeg_start_decompress(info); + while (info->output_scanline < info->output_height) { + uchar *row = outImage->scanLine(info->output_scanline); + (void) jpeg_read_scanlines(info, &row, 1); } } - if (cinfo.output_scanline == cinfo.output_height) - (void) jpeg_finish_decompress(&cinfo); + if (info->output_scanline == info->output_height) + (void) jpeg_finish_decompress(info); - if (cinfo.density_unit == 1) { - outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54)); - outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54)); - } else if (cinfo.density_unit == 2) { - outImage->setDotsPerMeterX(int(100. * cinfo.X_density)); - outImage->setDotsPerMeterY(int(100. * cinfo.Y_density)); + if (info->density_unit == 1) { + outImage->setDotsPerMeterX(int(100. * info->X_density / 2.54)); + outImage->setDotsPerMeterY(int(100. * info->Y_density / 2.54)); + } else if (info->density_unit == 2) { + outImage->setDotsPerMeterX(int(100. * info->X_density)); + outImage->setDotsPerMeterY(int(100. * info->Y_density)); } if (scaledSize.isValid() && scaledSize != clip.size()) { *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, quality >= HIGH_QUALITY_THRESHOLD ? Qt::SmoothTransformation : Qt::FastTransformation); } - } - jpeg_destroy_decompress(&cinfo); - delete iod_src; - if (!scaledClipRect.isEmpty()) - *outImage = outImage->copy(scaledClipRect); - return !outImage->isNull(); + if (!scaledClipRect.isEmpty()) + *outImage = outImage->copy(scaledClipRect); + return !outImage->isNull(); + } + else + return false; } - struct my_jpeg_destination_mgr : public jpeg_destination_mgr { // Nothing dynamic - cannot rely on destruction over longjump QIODevice *device; @@ -745,18 +678,124 @@ static bool write_jpeg_image(const QImage &sourceImage, QIODevice *device, int s return success; } +class QJpegHandlerPrivate +{ +public: + enum State { + Ready, + ReadHeader, + Error + }; + + QJpegHandlerPrivate(QJpegHandler *qq) + : quality(75), iod_src(0), state(Ready), q(qq) + {} + + ~QJpegHandlerPrivate() + { + if(iod_src) + { + jpeg_destroy_decompress(&info); + delete iod_src; + iod_src = 0; + } + } + + bool readJpegHeader(QIODevice*); + bool read(QImage *image); + + int quality; + QVariant size; + QImage::Format format; + QSize scaledSize; + QRect scaledClipRect; + QRect clipRect; + struct jpeg_decompress_struct info; + struct my_jpeg_source_mgr * iod_src; + struct my_error_mgr err; + + State state; + + QJpegHandler *q; +}; + +/*! + \internal +*/ +bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) +{ + if(state == Ready) + { + state = Error; + iod_src = new my_jpeg_source_mgr(device); + + jpeg_create_decompress(&info); + info.src = iod_src; + info.err = jpeg_std_error(&err); + err.error_exit = my_error_exit; + + if (!setjmp(err.setjmp_buffer)) { + #if defined(Q_OS_UNIXWARE) + (void) jpeg_read_header(&info, B_TRUE); + #else + (void) jpeg_read_header(&info, true); + #endif + + int width = 0; + int height = 0; + read_jpeg_size(width, height, &info); + size = QSize(width, height); + + format = QImage::Format_Invalid; + read_jpeg_format(format, &info); + state = ReadHeader; + return true; + } + else + { + return false; + } + } + else if(state == Error) + return false; + return true; +} + +bool QJpegHandlerPrivate::read(QImage *image) +{ + if(state == Ready) + readJpegHeader(q->device()); + + if(state == ReadHeader) + { + bool success = read_jpeg_image(image, scaledSize, scaledClipRect, clipRect, quality, &info, &err); + state = success ? Ready : Error; + return success; + } + + return false; + +} + QJpegHandler::QJpegHandler() + : d(new QJpegHandlerPrivate(this)) +{ +} + +QJpegHandler::~QJpegHandler() { - quality = 75; + delete d; } bool QJpegHandler::canRead() const { - if (canRead(device())) { + if(d->state == QJpegHandlerPrivate::Ready) { + if (!canRead(device())) + return false; setFormat("jpeg"); return true; } - return false; + return d->state != QJpegHandlerPrivate::Error; } bool QJpegHandler::canRead(QIODevice *device) @@ -769,7 +808,6 @@ bool QJpegHandler::canRead(QIODevice *device) char buffer[2]; if (device->peek(buffer, 2) != 2) return false; - return uchar(buffer[0]) == 0xff && uchar(buffer[1]) == 0xd8; } @@ -777,12 +815,12 @@ bool QJpegHandler::read(QImage *image) { if (!canRead()) return false; - return read_jpeg_image(device(), image, scaledSize, scaledClipRect, clipRect, quality); + return d->read(image); } bool QJpegHandler::write(const QImage &image) { - return write_jpeg_image(image, device(), quality); + return write_jpeg_image(image, device(), d->quality); } bool QJpegHandler::supportsOption(ImageOption option) const @@ -799,32 +837,19 @@ QVariant QJpegHandler::option(ImageOption option) const { switch(option) { case Quality: - return quality; + return d->quality; case ScaledSize: - return scaledSize; + return d->scaledSize; case ScaledClipRect: - return scaledClipRect; + return d->scaledClipRect; case ClipRect: - return clipRect; + return d->clipRect; case Size: - if (canRead() && !device()->isSequential()) { - qint64 pos = device()->pos(); - int width = 0; - int height = 0; - read_jpeg_size(device(), width, height); - device()->seek(pos); - return QSize(width, height); - } - return QVariant(); + d->readJpegHeader(device()); + return d->size; case ImageFormat: - if (canRead() && !device()->isSequential()) { - qint64 pos = device()->pos(); - QImage::Format format = QImage::Format_Invalid; - read_jpeg_format(device(), format); - device()->seek(pos); - return format; - } - return QImage::Format_Invalid; + d->readJpegHeader(device()); + return d->format; default: return QVariant(); } @@ -834,16 +859,16 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) { switch(option) { case Quality: - quality = value.toInt(); + d->quality = value.toInt(); break; case ScaledSize: - scaledSize = value.toSize(); + d->scaledSize = value.toSize(); break; case ScaledClipRect: - scaledClipRect = value.toRect(); + d->scaledClipRect = value.toRect(); break; case ClipRect: - clipRect = value.toRect(); + d->clipRect = value.toRect(); break; default: break; @@ -855,4 +880,7 @@ QByteArray QJpegHandler::name() const return "jpeg"; } + + + QT_END_NAMESPACE diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h index dfb6b47..c879f21 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.h +++ b/src/plugins/imageformats/jpeg/qjpeghandler.h @@ -48,10 +48,12 @@ QT_BEGIN_NAMESPACE +class QJpegHandlerPrivate; class QJpegHandler : public QImageIOHandler { public: QJpegHandler(); + ~QJpegHandler(); bool canRead() const; bool read(QImage *image); @@ -66,10 +68,7 @@ public: bool supportsOption(ImageOption option) const; private: - int quality; - QSize scaledSize; - QRect scaledClipRect; - QRect clipRect; + QJpegHandlerPrivate *d; }; QT_END_NAMESPACE diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index da41f18..85415b2 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -77,23 +77,25 @@ SOURCES += \ # Test for whether the build environment supports video rendering to graphics # surfaces. -exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) { - HEADERS += \ - $$PHONON_MMF_DIR/videooutput_surface.h \ - $$PHONON_MMF_DIR/videoplayer_surface.h - SOURCES += \ - $$PHONON_MMF_DIR/videooutput_surface.cpp \ - $$PHONON_MMF_DIR/videoplayer_surface.cpp - DEFINES += PHONON_MMF_VIDEO_SURFACES -} else { - HEADERS += \ - $$PHONON_MMF_DIR/ancestormovemonitor.h \ - $$PHONON_MMF_DIR/videooutput_dsa.h \ - $$PHONON_MMF_DIR/videoplayer_dsa.h - SOURCES += \ - $$PHONON_MMF_DIR/ancestormovemonitor.cpp \ - $$PHONON_MMF_DIR/videooutput_dsa.cpp \ - $$PHONON_MMF_DIR/videoplayer_dsa.cpp \ +symbian { + exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) { + HEADERS += \ + $$PHONON_MMF_DIR/videooutput_surface.h \ + $$PHONON_MMF_DIR/videoplayer_surface.h + SOURCES += \ + $$PHONON_MMF_DIR/videooutput_surface.cpp \ + $$PHONON_MMF_DIR/videoplayer_surface.cpp + DEFINES += PHONON_MMF_VIDEO_SURFACES + } else { + HEADERS += \ + $$PHONON_MMF_DIR/ancestormovemonitor.h \ + $$PHONON_MMF_DIR/videooutput_dsa.h \ + $$PHONON_MMF_DIR/videoplayer_dsa.h + SOURCES += \ + $$PHONON_MMF_DIR/ancestormovemonitor.cpp \ + $$PHONON_MMF_DIR/videooutput_dsa.cpp \ + $$PHONON_MMF_DIR/videoplayer_dsa.cpp \ + } } LIBS += -lcone |