From 2cc342a88282c3a5017057c6fd09658ff5d0294e Mon Sep 17 00:00:00 2001 From: Tom Sutcliffe Date: Fri, 4 Mar 2011 13:43:25 +0100 Subject: [PATCH] Fix for crash when stopping running an app over CODA TCP --- .../qt4projectmanager/qt-s60/codaruncontrol.cpp | 2 +- .../qt-s60/s60deployconfigurationwidget.cpp | 363 +++++++++++---------- src/shared/symbianutils/symbiandevicemanager.cpp | 20 +- src/shared/symbianutils/symbiandevicemanager.h | 2 +- 4 files changed, 194 insertions(+), 193 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp b/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp index 00f57c365b..2cb0a78d54 100644 --- a/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/codaruncontrol.cpp @@ -134,7 +134,7 @@ bool CodaRunControl::setupLauncher() m_codaDevice->sendSerialPing(false); } else { // For TCP we don't use device manager, we just set it up directly - m_codaDevice = QSharedPointer(new Coda::CodaDevice); + m_codaDevice = QSharedPointer(new Coda::CodaDevice, &QObject::deleteLater); // finishRunControl, which deletes m_codaDevice, can get called from within a coda callback, so need to use deleteLater connect(m_codaDevice.data(), SIGNAL(error(QString)), this, SLOT(slotError(QString))); connect(m_codaDevice.data(), SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(QString))); connect(m_codaDevice.data(), SIGNAL(tcfEvent(Coda::CodaEvent)), this, SLOT(slotCodaEvent(Coda::CodaEvent))); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp index a86e12547b..2cd4bb2457 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfigurationwidget.cpp @@ -550,189 +550,190 @@ void S60DeployConfigurationWidget::updateDeviceInfo() setDeviceInfoLabel(tr("Currently there is no information about the device for this connection type."), true); } - void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result) - { - if (result.type == Coda::CodaCommandResult::FailReply) { - setDeviceInfoLabel(tr("No device information available"), true); - m_deviceInfoButton->setEnabled(true); - return; - } else if (result.type == Coda::CodaCommandResult::CommandErrorReply){ - QString message; - startTable(message); - QTextStream str(&message); - addErrorToTable(str, tr("Qt version: "), tr("Not installed on device")); - finishTable(message); - setDeviceInfoLabel(message, false); - } else { - QString resultString; - if (result.values.count()) { - QHash obj = result.values[0].toVariant().toHash(); - QString ver = obj.value("qVersion").toString(); - - startTable(resultString); - QTextStream str(&resultString); - addToTable(str, tr("Qt version:"), ver); - QString systemVersion; - - int symVer = obj.value("symbianVersion").toInt(); - // Ugh why won't QSysInfo define these on non-symbian builds... - switch (symVer) { - case 10: - systemVersion.append("Symbian OS v9.2"); - break; - case 20: - systemVersion.append("Symbian OS v9.3"); - break; - case 30: - systemVersion.append("Symbian OS v9.4 / Symbian^1"); - break; - case 40: - systemVersion.append("Symbian^2"); - break; - case 50: - systemVersion.append("Symbian^3"); - break; - case 60: - systemVersion.append("Symbian^4"); - break; - default: - systemVersion.append(tr("Unrecognised Symbian version 0x%1").arg(symVer, 0, 16)); - break; - } - systemVersion.append(", "); - int s60Ver = obj.value("s60Version").toInt(); - switch (s60Ver) { - case 10: - systemVersion.append("S60 3rd Edition Feature Pack 1"); - break; - case 20: - systemVersion.append("S60 3rd Edition Feature Pack 2"); - break; - case 30: - systemVersion.append("S60 5th Edition"); - break; - case 40: - systemVersion.append("S60 5th Edition Feature Pack 1"); - break; - case 50: - systemVersion.append("S60 5th Edition Feature Pack 2"); - break; - default: - systemVersion.append(tr("Unrecognised S60 version 0x%1").arg(symVer, 0, 16)); - break; - } - addToTable(str, tr("OS version:"), systemVersion); - finishTable(resultString); - } - setDeviceInfoLabel(resultString); - } - m_codaInfoDevice->sendSymbianOsDataGetRomInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getRomInfoResult)); - } - - void S60DeployConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result) - { - if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { - QString resultString = m_deviceInfoLabel->text(); - startTable(resultString); - QTextStream str(&resultString); - - QVariantHash obj = result.values[0].toVariant().toHash(); - QString romVersion = obj.value("romVersion", tr("unknown")).toString(); - romVersion.replace('\n', " "); // The ROM string is split across multiple lines, for some reason. - addToTable(str, tr("ROM version:"), romVersion); - - QString pr = obj.value("prInfo").toString(); - if (pr.length()) - addToTable(str, tr("Release:"), pr); - finishTable(resultString); - setDeviceInfoLabel(resultString); - } - - QList packagesOfInterest; - packagesOfInterest.append(CODA_UID); - packagesOfInterest.append(QTMOBILITY_UID); - m_codaInfoDevice->sendSymbianInstallGetPackageInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getInstalledPackagesResult), packagesOfInterest); - } - - void S60DeployConfigurationWidget::getInstalledPackagesResult(const Coda::CodaCommandResult &result) - { - if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { - QString resultString = m_deviceInfoLabel->text(); - startTable(resultString); - QTextStream str(&resultString); - - QVariantList resultsList = result.values[0].toVariant().toList(); - foreach (const QVariant& var, resultsList) { - QVariantHash obj = var.toHash(); - bool ok = false; - uint uid = obj.value("uid").toString().toUInt(&ok, 16); - if (ok) { - bool error = !obj.value("error").isNull(); - QString versionString; - if (!error) { - QVariantList version = obj.value("version").toList(); - versionString = QString("%1.%2.%3").arg(version[0].toInt()) - .arg(version[1].toInt()) - .arg(version[2].toInt()); - } - switch (uid) { - case CODA_UID: { - if (error) { - // How can coda not be installed? Presumably some UID wrongness... - addErrorToTable(str, tr("CODA version: "), tr("Error reading CODA version")); - } else - addToTable(str, tr("CODA version: "), versionString); - } +void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::FailReply) { + setDeviceInfoLabel(tr("No device information available"), true); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); + m_deviceInfoButton->setEnabled(true); + return; + } else if (result.type == Coda::CodaCommandResult::CommandErrorReply){ + QString message; + startTable(message); + QTextStream str(&message); + addErrorToTable(str, tr("Qt version: "), tr("Not installed on device")); + finishTable(message); + setDeviceInfoLabel(message, false); + } else { + QString resultString; + if (result.values.count()) { + QHash obj = result.values[0].toVariant().toHash(); + QString ver = obj.value("qVersion").toString(); + + startTable(resultString); + QTextStream str(&resultString); + addToTable(str, tr("Qt version:"), ver); + QString systemVersion; + + int symVer = obj.value("symbianVersion").toInt(); + // Ugh why won't QSysInfo define these on non-symbian builds... + switch (symVer) { + case 10: + systemVersion.append("Symbian OS v9.2"); + break; + case 20: + systemVersion.append("Symbian OS v9.3"); + break; + case 30: + systemVersion.append("Symbian OS v9.4 / Symbian^1"); + break; + case 40: + systemVersion.append("Symbian^2"); + break; + case 50: + systemVersion.append("Symbian^3"); + break; + case 60: + systemVersion.append("Symbian^4"); break; - case QTMOBILITY_UID: { - if (error) - addErrorToTable(str, tr("QtMobility version: "), tr("Error reading QtMobility version")); - else - addToTable(str, tr("QtMobility version: "), versionString); - } + default: + systemVersion.append(tr("Unrecognised Symbian version 0x%1").arg(symVer, 0, 16)); break; - default: break; - } - } - } - finishTable(resultString); - setDeviceInfoLabel(resultString); - } - - QStringList keys; - keys << QLatin1String("EDisplayXPixels"); - keys << QLatin1String("EDisplayYPixels"); - //keys << "EMemoryRAMFree"; - m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getHalResult), keys); - } - - void S60DeployConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result) - { - if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { - QString resultString = m_deviceInfoLabel->text(); - QVariantList resultsList = result.values[0].toVariant().toList(); - int x = 0; - int y = 0; - foreach (const QVariant& var, resultsList) { - QVariantHash obj = var.toHash(); - if (obj.value("name").toString() == "EDisplayXPixels") - x = obj.value("value").toInt(); - else if (obj.value("name").toString() == "EDisplayYPixels") - y = obj.value("value").toInt(); - } - if (x && y) { - startTable(resultString); - QTextStream str(&resultString); - addToTable(str, tr("Screen size:"), QString("%1x%2").arg(x).arg(y)); - finishTable(resultString); - setDeviceInfoLabel(resultString); - } - } - - // Done with collecting info - m_deviceInfoButton->setEnabled(true); - SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); - } + } + systemVersion.append(", "); + int s60Ver = obj.value("s60Version").toInt(); + switch (s60Ver) { + case 10: + systemVersion.append("S60 3rd Edition Feature Pack 1"); + break; + case 20: + systemVersion.append("S60 3rd Edition Feature Pack 2"); + break; + case 30: + systemVersion.append("S60 5th Edition"); + break; + case 40: + systemVersion.append("S60 5th Edition Feature Pack 1"); + break; + case 50: + systemVersion.append("S60 5th Edition Feature Pack 2"); + break; + default: + systemVersion.append(tr("Unrecognised S60 version 0x%1").arg(symVer, 0, 16)); + break; + } + addToTable(str, tr("OS version:"), systemVersion); + finishTable(resultString); + } + setDeviceInfoLabel(resultString); + } + m_codaInfoDevice->sendSymbianOsDataGetRomInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getRomInfoResult)); +} + +void S60DeployConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { + QString resultString = m_deviceInfoLabel->text(); + startTable(resultString); + QTextStream str(&resultString); + + QVariantHash obj = result.values[0].toVariant().toHash(); + QString romVersion = obj.value("romVersion", tr("unknown")).toString(); + romVersion.replace('\n', " "); // The ROM string is split across multiple lines, for some reason. + addToTable(str, tr("ROM version:"), romVersion); + + QString pr = obj.value("prInfo").toString(); + if (pr.length()) + addToTable(str, tr("Release:"), pr); + finishTable(resultString); + setDeviceInfoLabel(resultString); + } + + QList packagesOfInterest; + packagesOfInterest.append(CODA_UID); + packagesOfInterest.append(QTMOBILITY_UID); + m_codaInfoDevice->sendSymbianInstallGetPackageInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getInstalledPackagesResult), packagesOfInterest); +} + +void S60DeployConfigurationWidget::getInstalledPackagesResult(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { + QString resultString = m_deviceInfoLabel->text(); + startTable(resultString); + QTextStream str(&resultString); + + QVariantList resultsList = result.values[0].toVariant().toList(); + foreach (const QVariant& var, resultsList) { + QVariantHash obj = var.toHash(); + bool ok = false; + uint uid = obj.value("uid").toString().toUInt(&ok, 16); + if (ok) { + bool error = !obj.value("error").isNull(); + QString versionString; + if (!error) { + QVariantList version = obj.value("version").toList(); + versionString = QString("%1.%2.%3").arg(version[0].toInt()) + .arg(version[1].toInt()) + .arg(version[2].toInt()); + } + switch (uid) { + case CODA_UID: { + if (error) { + // How can coda not be installed? Presumably some UID wrongness... + addErrorToTable(str, tr("CODA version: "), tr("Error reading CODA version")); + } else + addToTable(str, tr("CODA version: "), versionString); + } + break; + case QTMOBILITY_UID: { + if (error) + addErrorToTable(str, tr("QtMobility version: "), tr("Error reading QtMobility version")); + else + addToTable(str, tr("QtMobility version: "), versionString); + } + break; + default: break; + } + } + } + finishTable(resultString); + setDeviceInfoLabel(resultString); + } + + QStringList keys; + keys << QLatin1String("EDisplayXPixels"); + keys << QLatin1String("EDisplayYPixels"); + //keys << "EMemoryRAMFree"; + m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getHalResult), keys); +} + +void S60DeployConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result) +{ + if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { + QString resultString = m_deviceInfoLabel->text(); + QVariantList resultsList = result.values[0].toVariant().toList(); + int x = 0; + int y = 0; + foreach (const QVariant& var, resultsList) { + QVariantHash obj = var.toHash(); + if (obj.value("name").toString() == "EDisplayXPixels") + x = obj.value("value").toInt(); + else if (obj.value("name").toString() == "EDisplayYPixels") + y = obj.value("value").toInt(); + } + if (x && y) { + startTable(resultString); + QTextStream str(&resultString); + addToTable(str, tr("Screen size:"), QString("%1x%2").arg(x).arg(y)); + finishTable(resultString); + setDeviceInfoLabel(resultString); + } + } + + // Done with collecting info + m_deviceInfoButton->setEnabled(true); + SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); +} } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/shared/symbianutils/symbiandevicemanager.cpp b/src/shared/symbianutils/symbiandevicemanager.cpp index 5d340b5062..9ddb1c2d2b 100644 --- a/src/shared/symbianutils/symbiandevicemanager.cpp +++ b/src/shared/symbianutils/symbiandevicemanager.cpp @@ -274,7 +274,7 @@ struct SymbianDeviceManagerPrivate { //QSignalMapper *m_destroyReleaseMapper; // The following 2 variables are needed to manage requests for a TCF port not coming from the main thread int m_constructTcfPortEventType; - QMutex m_tcfPortWaitMutex; + QMutex m_codaPortWaitMutex; }; class QConstructTcfPortEvent : public QEvent @@ -375,16 +375,16 @@ CodaDevicePtr SymbianDeviceManager::getCodaDevice(const QString &port) // Check we instanciate in the correct thread - we can't afford to create the CodaDevice (and more specifically, open the VirtualSerialDevice) in a thread that isn't guaranteed to be long-lived. // Therefore, if we're not in SymbianDeviceManager's thread, rejig things so it's opened in the main thread if (QThread::currentThread() != thread()) { - // SymbianDeviceManager is owned by the current thread - d->m_tcfPortWaitMutex.lock(); + // SymbianDeviceManager is owned by the main thread + d->m_codaPortWaitMutex.lock(); QWaitCondition waiter; QCoreApplication::postEvent(this, new QConstructTcfPortEvent((QEvent::Type)d->m_constructTcfPortEventType, port, &devicePtr, &waiter)); - waiter.wait(&d->m_tcfPortWaitMutex); + waiter.wait(&d->m_codaPortWaitMutex); // When the wait returns (due to the wakeAll in SymbianDeviceManager::customEvent), the CodaDevice will be fully set up - d->m_tcfPortWaitMutex.unlock(); + d->m_codaPortWaitMutex.unlock(); } else { // We're in the main thread, just set it up directly - constructTcfPort(devicePtr, port); + constructCodaPort(devicePtr, port); } // We still carry on in the case we failed to open so the client can access the IODevice's errorString() } @@ -393,9 +393,9 @@ CodaDevicePtr SymbianDeviceManager::getCodaDevice(const QString &port) return devicePtr; } -void SymbianDeviceManager::constructTcfPort(CodaDevicePtr& device, const QString& portName) +void SymbianDeviceManager::constructCodaPort(CodaDevicePtr& device, const QString& portName) { - QMutexLocker locker(&d->m_tcfPortWaitMutex); + QMutexLocker locker(&d->m_codaPortWaitMutex); if (device.isNull()) { device = QSharedPointer(new Coda::CodaDevice); const QSharedPointer serialDevice(new SymbianUtils::VirtualSerialDevice(portName)); @@ -414,7 +414,7 @@ void SymbianDeviceManager::customEvent(QEvent *event) { if (event->type() == d->m_constructTcfPortEventType) { QConstructTcfPortEvent* constructEvent = static_cast(event); - constructTcfPort(*constructEvent->m_device, constructEvent->m_portName); + constructCodaPort(*constructEvent->m_device, constructEvent->m_portName); constructEvent->m_waiter->wakeAll(); // Should only ever be one thing waiting on this } } @@ -680,7 +680,7 @@ qint64 OstChannel::readData(char *data, qint64 maxSize) qint64 OstChannel::writeData(const char *data, qint64 maxSize) { - static const qint64 KMaxOstPayload = 1022; + static const qint64 KMaxOstPayload = 1024; // If necessary, split the packet up while (maxSize) { QByteArray dataBuf = QByteArray::fromRawData(data, qMin(KMaxOstPayload, maxSize)); diff --git a/src/shared/symbianutils/symbiandevicemanager.h b/src/shared/symbianutils/symbiandevicemanager.h index 35753f8612..e53783b839 100644 --- a/src/shared/symbianutils/symbiandevicemanager.h +++ b/src/shared/symbianutils/symbiandevicemanager.h @@ -186,7 +186,7 @@ private: SymbianDeviceList serialPorts() const; SymbianDeviceList blueToothDevices() const; void customEvent(QEvent *event); - void constructTcfPort(CodaDevicePtr& device, const QString& portName); + void constructCodaPort(CodaDevicePtr& device, const QString& portName); SymbianDeviceManagerPrivate *d; }; -- 2.11.0