forked from qt-creator/qt-creator
Qnx: Fixing UI freeze when canceling SSH-keys generation
The UI freeze happens when an user cancels 'Add BlackBerry Device' wizard while SSH-keys are being generated. Removing a need for terminate() and wait() calls in BlackBerryDeviceConfigurationWizardSshKeyPage dtor by invoking a new thread each time a Generate button is pressed. Such a thread can delete itself later when the calculation is finished. The only drawback is that the calculation is still happening even when the wizard is closed. Just the calculation results are not used anywhere. Task-number: QTCREATORBUG-9888 Change-Id: Ibc5e98d08e129d7f76620a5dea9ed5190932243b Reviewed-by: Mehdi Fekari <mfekari@blackberry.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
committed by
Tobias Hunger
parent
8d6e995c82
commit
bd064d50e6
@@ -162,7 +162,6 @@ void BlackBerryDeviceConfigurationWizardSetupPage::requestDebugToken()
|
|||||||
BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWizardSshKeyPage(QWidget *parent)
|
BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWizardSshKeyPage(QWidget *parent)
|
||||||
: QWizardPage(parent)
|
: QWizardPage(parent)
|
||||||
, m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage)
|
, m_ui(new Ui::BlackBerryDeviceConfigurationWizardSshKeyPage)
|
||||||
, m_sshKeysGenerator(new BlackBerrySshKeysGenerator(this))
|
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
@@ -180,15 +179,10 @@ BlackBerryDeviceConfigurationWizardSshKeyPage::BlackBerryDeviceConfigurationWiza
|
|||||||
connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SLOT(findMatchingPublicKey(QString)));
|
connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SLOT(findMatchingPublicKey(QString)));
|
||||||
connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SIGNAL(completeChanged()));
|
connect(m_ui->privateKey, SIGNAL(changed(QString)), this, SIGNAL(completeChanged()));
|
||||||
connect(m_ui->generate, SIGNAL(clicked()), this, SLOT(generateSshKeys()));
|
connect(m_ui->generate, SIGNAL(clicked()), this, SLOT(generateSshKeys()));
|
||||||
connect(m_sshKeysGenerator, SIGNAL(sshKeysGenerationFinished(bool)), this, SLOT(processSshKeys(bool)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackBerryDeviceConfigurationWizardSshKeyPage::~BlackBerryDeviceConfigurationWizardSshKeyPage()
|
BlackBerryDeviceConfigurationWizardSshKeyPage::~BlackBerryDeviceConfigurationWizardSshKeyPage()
|
||||||
{
|
{
|
||||||
// Make sure the m_sshKeysGenerator thread is terminated before it's destroyed
|
|
||||||
m_sshKeysGenerator->terminate();
|
|
||||||
m_sshKeysGenerator->wait();
|
|
||||||
|
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
m_ui = 0;
|
m_ui = 0;
|
||||||
}
|
}
|
||||||
@@ -224,42 +218,43 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const
|
|||||||
m_ui->publicKey->clear();
|
m_ui->publicKey->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(bool success)
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::sshKeysGenerationFailed(const QString &error)
|
||||||
|
{
|
||||||
|
setBusy(false);
|
||||||
|
QMessageBox::critical(this, tr("Key Generation Failed"), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(const QString &privateKeyPath, const QByteArray &privateKey, const QByteArray &publicKey)
|
||||||
{
|
{
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
|
|
||||||
if (!success) {
|
const QString publicKeyPath = privateKeyPath + QLatin1String(".pub");
|
||||||
QMessageBox::critical(this, tr("Key Generation Failed"), m_sshKeysGenerator->error());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString publicKeyPath = m_generatedPrivateKeyPath + QLatin1String(".pub");
|
if (!saveKeys(privateKey, publicKey, privateKeyPath, publicKeyPath)) // saveKeys(..) will show an error message if necessary
|
||||||
|
|
||||||
if (!saveKeys(m_generatedPrivateKeyPath, publicKeyPath)) // saveKeys(..) will show an error message if necessary
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_ui->privateKey->setFileName(Utils::FileName::fromString(m_generatedPrivateKeyPath));
|
m_ui->privateKey->setFileName(Utils::FileName::fromString(privateKeyPath));
|
||||||
m_ui->publicKey->setText(QDir::toNativeSeparators(publicKeyPath));
|
m_ui->publicKey->setText(QDir::toNativeSeparators(publicKeyPath));
|
||||||
|
|
||||||
emit completeChanged();
|
emit completeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlackBerryDeviceConfigurationWizardSshKeyPage::saveKeys(const QString &privateKeyFile, const QString &publicKeyFile)
|
bool BlackBerryDeviceConfigurationWizardSshKeyPage::saveKeys(const QByteArray &privateKey, const QByteArray &publicKey, const QString &privateKeyPath, const QString &publicKeyPath)
|
||||||
{
|
{
|
||||||
Utils::FileSaver privSaver(privateKeyFile);
|
Utils::FileSaver privSaver(privateKeyPath);
|
||||||
privSaver.write(m_sshKeysGenerator->keyGenerator()->privateKey());
|
privSaver.write(privateKey);
|
||||||
if (!privSaver.finalize(this))
|
if (!privSaver.finalize(this))
|
||||||
return false; // finalize shows an error message if necessary
|
return false; // finalize shows an error message if necessary
|
||||||
QFile::setPermissions(privateKeyFile, QFile::ReadOwner | QFile::WriteOwner);
|
QFile::setPermissions(privateKeyPath, QFile::ReadOwner | QFile::WriteOwner);
|
||||||
|
|
||||||
Utils::FileSaver pubSaver(publicKeyFile);
|
Utils::FileSaver pubSaver(publicKeyPath);
|
||||||
|
|
||||||
// blackberry-connect requires an @ character to be included in the RSA comment
|
// blackberry-connect requires an @ character to be included in the RSA comment
|
||||||
const QString atHost = QLatin1Char('@') + QHostInfo::localHostName();
|
const QString atHost = QLatin1Char('@') + QHostInfo::localHostName();
|
||||||
QByteArray pubKeyContent = m_sshKeysGenerator->keyGenerator()->publicKey();
|
QByteArray pubKeyContent = publicKey;
|
||||||
pubKeyContent.append(atHost.toLocal8Bit());
|
pubKeyContent.append(atHost.toLocal8Bit());
|
||||||
|
|
||||||
pubSaver.write(pubKeyContent);
|
pubSaver.write(publicKey);
|
||||||
if (!pubSaver.finalize(this))
|
if (!pubSaver.finalize(this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -276,10 +271,11 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::generateSshKeys()
|
|||||||
if (privateKeyPath.isEmpty())
|
if (privateKeyPath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_generatedPrivateKeyPath = privateKeyPath;
|
|
||||||
|
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
m_sshKeysGenerator->start();
|
BlackBerrySshKeysGenerator *sshKeysGenerator = new BlackBerrySshKeysGenerator(privateKeyPath);
|
||||||
|
connect(sshKeysGenerator, SIGNAL(sshKeysGenerationFailed(QString)), this, SLOT(sshKeysGenerationFailed(QString)), Qt::QueuedConnection);
|
||||||
|
connect(sshKeysGenerator, SIGNAL(sshKeysGenerationFinished(QString,QByteArray,QByteArray)), this, SLOT(processSshKeys(QString,QByteArray,QByteArray)), Qt::QueuedConnection);
|
||||||
|
sshKeysGenerator->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlackBerryDeviceConfigurationWizardSshKeyPage::setBusy(bool busy)
|
void BlackBerryDeviceConfigurationWizardSshKeyPage::setBusy(bool busy)
|
||||||
|
@@ -87,17 +87,16 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void findMatchingPublicKey(const QString &privateKeyPath);
|
void findMatchingPublicKey(const QString &privateKeyPath);
|
||||||
void processSshKeys(bool success);
|
|
||||||
|
void sshKeysGenerationFailed(const QString &error);
|
||||||
|
void processSshKeys(const QString &privateKeyPath, const QByteArray &privateKey, const QByteArray &publicKey);
|
||||||
void generateSshKeys();
|
void generateSshKeys();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool saveKeys(const QString &privateKeyFile, const QString &publicKeyFile);
|
bool saveKeys(const QByteArray &privateKey, const QByteArray &publicKey, const QString &privateKeyPath, const QString &publicKeyPath);
|
||||||
void setBusy(bool busy);
|
void setBusy(bool busy);
|
||||||
|
|
||||||
Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui;
|
Ui::BlackBerryDeviceConfigurationWizardSshKeyPage *m_ui;
|
||||||
|
|
||||||
BlackBerrySshKeysGenerator *m_sshKeysGenerator;
|
|
||||||
QString m_generatedPrivateKeyPath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlackBerryDeviceConfigurationWizardFinalPage : public QWizardPage
|
class BlackBerryDeviceConfigurationWizardFinalPage : public QWizardPage
|
||||||
|
@@ -34,10 +34,12 @@
|
|||||||
|
|
||||||
using namespace Qnx::Internal;
|
using namespace Qnx::Internal;
|
||||||
|
|
||||||
BlackBerrySshKeysGenerator::BlackBerrySshKeysGenerator(QObject *parent)
|
BlackBerrySshKeysGenerator::BlackBerrySshKeysGenerator(const QString &privateKeyPath)
|
||||||
: QThread(parent)
|
: QThread(0)
|
||||||
, m_keyGen(new QSsh::SshKeyGenerator)
|
, m_keyGen(new QSsh::SshKeyGenerator)
|
||||||
|
, m_privateKeyPath(privateKeyPath)
|
||||||
{
|
{
|
||||||
|
connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackBerrySshKeysGenerator::~BlackBerrySshKeysGenerator()
|
BlackBerrySshKeysGenerator::~BlackBerrySshKeysGenerator()
|
||||||
@@ -51,15 +53,8 @@ void BlackBerrySshKeysGenerator::run()
|
|||||||
const bool success = m_keyGen->generateKeys(QSsh::SshKeyGenerator::Rsa,
|
const bool success = m_keyGen->generateKeys(QSsh::SshKeyGenerator::Rsa,
|
||||||
QSsh::SshKeyGenerator::Mixed, 4096,
|
QSsh::SshKeyGenerator::Mixed, 4096,
|
||||||
QSsh::SshKeyGenerator::DoNotOfferEncryption);
|
QSsh::SshKeyGenerator::DoNotOfferEncryption);
|
||||||
emit sshKeysGenerationFinished(success);
|
if (success)
|
||||||
}
|
emit sshKeysGenerationFinished(m_privateKeyPath, m_keyGen->privateKey(), m_keyGen->publicKey());
|
||||||
|
else
|
||||||
QSsh::SshKeyGenerator *BlackBerrySshKeysGenerator::keyGenerator() const
|
emit sshKeysGenerationFailed(m_keyGen->error());
|
||||||
{
|
|
||||||
return m_keyGen;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString BlackBerrySshKeysGenerator::error() const
|
|
||||||
{
|
|
||||||
return m_keyGen->error();
|
|
||||||
}
|
}
|
||||||
|
@@ -44,16 +44,16 @@ class BlackBerrySshKeysGenerator : public QThread
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
BlackBerrySshKeysGenerator(QObject *parent = 0);
|
BlackBerrySshKeysGenerator(const QString &privateKeyPath);
|
||||||
~BlackBerrySshKeysGenerator();
|
~BlackBerrySshKeysGenerator();
|
||||||
QSsh::SshKeyGenerator *keyGenerator() const;
|
|
||||||
QString error() const;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sshKeysGenerationFinished(bool success);
|
void sshKeysGenerationFailed(const QString &error);
|
||||||
|
void sshKeysGenerationFinished(const QString &privateKeyPath, const QByteArray &privateKey, const QByteArray &publicKey);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSsh::SshKeyGenerator *m_keyGen;
|
QSsh::SshKeyGenerator *m_keyGen;
|
||||||
|
const QString m_privateKeyPath;
|
||||||
void run();
|
void run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user