Fix for crash when stopping running an app over CODA TCP

This commit is contained in:
Tom Sutcliffe
2011-03-04 13:43:25 +01:00
committed by Pawel Polanski
parent b9614cdf7d
commit 2cc342a882
4 changed files with 189 additions and 188 deletions

View File

@@ -134,7 +134,7 @@ bool CodaRunControl::setupLauncher()
m_codaDevice->sendSerialPing(false); m_codaDevice->sendSerialPing(false);
} else { } else {
// For TCP we don't use device manager, we just set it up directly // For TCP we don't use device manager, we just set it up directly
m_codaDevice = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice); m_codaDevice = QSharedPointer<Coda::CodaDevice>(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(error(QString)), this, SLOT(slotError(QString)));
connect(m_codaDevice.data(), SIGNAL(logMessage(QString)), this, SLOT(slotTrkLogMessage(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))); connect(m_codaDevice.data(), SIGNAL(tcfEvent(Coda::CodaEvent)), this, SLOT(slotCodaEvent(Coda::CodaEvent)));

View File

@@ -550,189 +550,190 @@ void S60DeployConfigurationWidget::updateDeviceInfo()
setDeviceInfoLabel(tr("Currently there is no information about the device for this connection type."), true); setDeviceInfoLabel(tr("Currently there is no information about the device for this connection type."), true);
} }
void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result) void S60DeployConfigurationWidget::getQtVersionCommandResult(const Coda::CodaCommandResult &result)
{ {
if (result.type == Coda::CodaCommandResult::FailReply) { if (result.type == Coda::CodaCommandResult::FailReply) {
setDeviceInfoLabel(tr("No device information available"), true); setDeviceInfoLabel(tr("No device information available"), true);
m_deviceInfoButton->setEnabled(true); SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice);
return; m_deviceInfoButton->setEnabled(true);
} else if (result.type == Coda::CodaCommandResult::CommandErrorReply){ return;
QString message; } else if (result.type == Coda::CodaCommandResult::CommandErrorReply){
startTable(message); QString message;
QTextStream str(&message); startTable(message);
addErrorToTable(str, tr("Qt version: "), tr("Not installed on device")); QTextStream str(&message);
finishTable(message); addErrorToTable(str, tr("Qt version: "), tr("Not installed on device"));
setDeviceInfoLabel(message, false); finishTable(message);
} else { setDeviceInfoLabel(message, false);
QString resultString; } else {
if (result.values.count()) { QString resultString;
QHash<QString, QVariant> obj = result.values[0].toVariant().toHash(); if (result.values.count()) {
QString ver = obj.value("qVersion").toString(); QHash<QString, QVariant> obj = result.values[0].toVariant().toHash();
QString ver = obj.value("qVersion").toString();
startTable(resultString); startTable(resultString);
QTextStream str(&resultString); QTextStream str(&resultString);
addToTable(str, tr("Qt version:"), ver); addToTable(str, tr("Qt version:"), ver);
QString systemVersion; QString systemVersion;
int symVer = obj.value("symbianVersion").toInt(); int symVer = obj.value("symbianVersion").toInt();
// Ugh why won't QSysInfo define these on non-symbian builds... // Ugh why won't QSysInfo define these on non-symbian builds...
switch (symVer) { switch (symVer) {
case 10: case 10:
systemVersion.append("Symbian OS v9.2"); 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<quint32> 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; break;
case QTMOBILITY_UID: { case 20:
if (error) systemVersion.append("Symbian OS v9.3");
addErrorToTable(str, tr("QtMobility version: "), tr("Error reading QtMobility version"));
else
addToTable(str, tr("QtMobility version: "), versionString);
}
break; break;
default: break; case 30:
} systemVersion.append("Symbian OS v9.4 / Symbian^1");
} break;
} case 40:
finishTable(resultString); systemVersion.append("Symbian^2");
setDeviceInfoLabel(resultString); 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));
}
QStringList keys; void S60DeployConfigurationWidget::getRomInfoResult(const Coda::CodaCommandResult &result)
keys << QLatin1String("EDisplayXPixels"); {
keys << QLatin1String("EDisplayYPixels"); if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) {
//keys << "EMemoryRAMFree"; QString resultString = m_deviceInfoLabel->text();
m_codaInfoDevice->sendSymbianOsDataGetHalInfoCommand(Coda::CodaCallback(this, &S60DeployConfigurationWidget::getHalResult), keys); startTable(resultString);
} QTextStream str(&resultString);
void S60DeployConfigurationWidget::getHalResult(const Coda::CodaCommandResult &result) QVariantHash obj = result.values[0].toVariant().toHash();
{ QString romVersion = obj.value("romVersion", tr("unknown")).toString();
if (result.type == Coda::CodaCommandResult::SuccessReply && result.values.count()) { romVersion.replace('\n', " "); // The ROM string is split across multiple lines, for some reason.
QString resultString = m_deviceInfoLabel->text(); addToTable(str, tr("ROM version:"), romVersion);
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 QString pr = obj.value("prInfo").toString();
m_deviceInfoButton->setEnabled(true); if (pr.length())
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaInfoDevice); addToTable(str, tr("Release:"), pr);
} finishTable(resultString);
setDeviceInfoLabel(resultString);
}
QList<quint32> 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 Internal
} // namespace Qt4ProjectManager } // namespace Qt4ProjectManager

View File

@@ -274,7 +274,7 @@ struct SymbianDeviceManagerPrivate {
//QSignalMapper *m_destroyReleaseMapper; //QSignalMapper *m_destroyReleaseMapper;
// The following 2 variables are needed to manage requests for a TCF port not coming from the main thread // The following 2 variables are needed to manage requests for a TCF port not coming from the main thread
int m_constructTcfPortEventType; int m_constructTcfPortEventType;
QMutex m_tcfPortWaitMutex; QMutex m_codaPortWaitMutex;
}; };
class QConstructTcfPortEvent : public QEvent 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. // 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 // Therefore, if we're not in SymbianDeviceManager's thread, rejig things so it's opened in the main thread
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
// SymbianDeviceManager is owned by the current thread // SymbianDeviceManager is owned by the main thread
d->m_tcfPortWaitMutex.lock(); d->m_codaPortWaitMutex.lock();
QWaitCondition waiter; QWaitCondition waiter;
QCoreApplication::postEvent(this, new QConstructTcfPortEvent((QEvent::Type)d->m_constructTcfPortEventType, port, &devicePtr, &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 // 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 { } else {
// We're in the main thread, just set it up directly // 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() // 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; 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()) { if (device.isNull()) {
device = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice); device = QSharedPointer<Coda::CodaDevice>(new Coda::CodaDevice);
const QSharedPointer<SymbianUtils::VirtualSerialDevice> serialDevice(new SymbianUtils::VirtualSerialDevice(portName)); const QSharedPointer<SymbianUtils::VirtualSerialDevice> serialDevice(new SymbianUtils::VirtualSerialDevice(portName));
@@ -414,7 +414,7 @@ void SymbianDeviceManager::customEvent(QEvent *event)
{ {
if (event->type() == d->m_constructTcfPortEventType) { if (event->type() == d->m_constructTcfPortEventType) {
QConstructTcfPortEvent* constructEvent = static_cast<QConstructTcfPortEvent*>(event); QConstructTcfPortEvent* constructEvent = static_cast<QConstructTcfPortEvent*>(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 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) qint64 OstChannel::writeData(const char *data, qint64 maxSize)
{ {
static const qint64 KMaxOstPayload = 1022; static const qint64 KMaxOstPayload = 1024;
// If necessary, split the packet up // If necessary, split the packet up
while (maxSize) { while (maxSize) {
QByteArray dataBuf = QByteArray::fromRawData(data, qMin(KMaxOstPayload, maxSize)); QByteArray dataBuf = QByteArray::fromRawData(data, qMin(KMaxOstPayload, maxSize));

View File

@@ -186,7 +186,7 @@ private:
SymbianDeviceList serialPorts() const; SymbianDeviceList serialPorts() const;
SymbianDeviceList blueToothDevices() const; SymbianDeviceList blueToothDevices() const;
void customEvent(QEvent *event); void customEvent(QEvent *event);
void constructTcfPort(CodaDevicePtr& device, const QString& portName); void constructCodaPort(CodaDevicePtr& device, const QString& portName);
SymbianDeviceManagerPrivate *d; SymbianDeviceManagerPrivate *d;
}; };