From ab372deb1fb7365eb9fb5d01b13bd3d2ea56706e Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Thu, 8 Jan 2015 17:05:09 +0100 Subject: [PATCH] Android: Reduce time to open settings widget Two major areas of improvement: - Make connections last, so that the initial setup does not trigger any unnecessary checks. - Make fetching the list of android virtual devices a background operation. Together they reduce the time needed to open the settings for me by roughly 10 times. Task-number: QTCREATORBUG-13735 Change-Id: I0839853dcdbdfe20a183a27888e55d3c56a9b815 Reviewed-by: BogDan Vatra --- src/plugins/android/androidconfigurations.cpp | 14 +++- src/plugins/android/androidconfigurations.h | 4 ++ src/plugins/android/androidsettingswidget.cpp | 61 ++++++++++++++--- src/plugins/android/androidsettingswidget.h | 7 ++ src/plugins/android/androidsettingswidget.ui | 66 +------------------ 5 files changed, 75 insertions(+), 77 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index cd54354a92e..9fe70a3d82e 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -600,12 +600,22 @@ bool AndroidConfig::removeAVD(const QString &name) const return !proc.exitCode(); } +QFuture> AndroidConfig::androidVirtualDevicesFuture() +{ + return QtConcurrent::run(&AndroidConfig::androidVirtualDevicesImpl, androidToolPath(), androidToolEnvironment()); +} + QVector AndroidConfig::androidVirtualDevices() const +{ + return androidVirtualDevicesImpl(androidToolPath(), androidToolEnvironment()); +} + +QVector AndroidConfig::androidVirtualDevicesImpl(const Utils::FileName &androidTool, const Utils::Environment &environment) { QVector devices; QProcess proc; - proc.setProcessEnvironment(androidToolEnvironment().toProcessEnvironment()); - proc.start(androidToolPath().toString(), + proc.setProcessEnvironment(environment.toProcessEnvironment()); + proc.start(androidTool.toString(), QStringList() << QLatin1String("list") << QLatin1String("avd")); // list available AVDs if (!proc.waitForFinished(5000)) { proc.terminate(); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index ba39917a279..105866de91a 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -146,7 +146,10 @@ public: bool removeAVD(const QString &name) const; QVector connectedDevices(QString *error = 0) const; + + QFuture > androidVirtualDevicesFuture(); QVector androidVirtualDevices() const; + QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const; bool startAVDAsync(const QString &avdName) const; QString findAvd(int apiLevel, const QString &cpuAbi) const; @@ -165,6 +168,7 @@ public: SdkPlatform highestAndroidSdk() const; private: static CreateAvdInfo createAVDImpl(CreateAvdInfo info, Utils::FileName androidToolPath, Utils::Environment env); + static QVector androidVirtualDevicesImpl(const Utils::FileName &androidTool, const Utils::Environment &environment); Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const; Utils::FileName openJDKBinPath() const; diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index c741286f1d8..f4397ebf8b3 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -170,7 +170,6 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent) m_ui->DataPartitionSizeSpinBox->setValue(m_androidConfig.partitionSize()); m_ui->CreateKitCheckBox->setChecked(m_androidConfig.automaticKitCreation()); m_ui->AVDTableView->setModel(&m_AVDModel); - m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices()); m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); @@ -180,11 +179,20 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent) connect(m_ui->gdbWarningLabel, SIGNAL(linkActivated(QString)), this, SLOT(showGdbWarningDialog())); + connect(&m_virtualDevicesWatcher, SIGNAL(finished()), + this, SLOT(updateAvds())); + check(All); applyToUi(All); connect(&m_futureWatcher, SIGNAL(finished()), this, SLOT(avdAdded())); + + connect(m_ui->NDKLocationPathChooser, SIGNAL(changed(QString)), this, SLOT(ndkLocationEditingFinished())); + connect(m_ui->SDKLocationPathChooser, SIGNAL(changed(QString)), this, SLOT(sdkLocationEditingFinished())); + connect(m_ui->AntLocationPathChooser, SIGNAL(changed(QString)), this, SLOT(antLocationEditingFinished())); + connect(m_ui->OpenJDKLocationPathChooser, SIGNAL(changed(QString)), this, SLOT(openJDKLocationEditingFinished())); + } AndroidSettingsWidget::~AndroidSettingsWidget() @@ -397,10 +405,41 @@ void AndroidSettingsWidget::applyToUi(AndroidSettingsWidget::Mode mode) m_ui->AVDManagerFrame->setEnabled(false); } - m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices()); + startUpdateAvd(); } } +void AndroidSettingsWidget::disableAvdControls() +{ + m_ui->AVDAddPushButton->setEnabled(false); + m_ui->AVDTableView->setEnabled(false); + m_ui->AVDRemovePushButton->setEnabled(false); + m_ui->AVDStartPushButton->setEnabled(false); +} + +void AndroidSettingsWidget::enableAvdControls() +{ + m_ui->AVDTableView->setEnabled(true); + m_ui->AVDAddPushButton->setEnabled(true); + avdActivated(m_ui->AVDTableView->currentIndex()); +} + +void AndroidSettingsWidget::startUpdateAvd() +{ + disableAvdControls(); + m_virtualDevicesWatcher.setFuture(m_androidConfig.androidVirtualDevicesFuture()); +} + +void AndroidSettingsWidget::updateAvds() +{ + m_AVDModel.setAvdList(m_virtualDevicesWatcher.result()); + if (!m_lastAddedAvd.isEmpty()) { + m_ui->AVDTableView->setCurrentIndex(m_AVDModel.indexForAvdName(m_lastAddedAvd)); + m_lastAddedAvd.clear(); + } + enableAvdControls(); +} + bool AndroidSettingsWidget::sdkLocationIsValid() const { Utils::FileName androidExe = m_androidConfig.sdkLocation(); @@ -519,11 +558,11 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl() void AndroidSettingsWidget::addAVD() { - m_ui->AVDAddPushButton->setEnabled(false); + disableAvdControls(); AndroidConfig::CreateAvdInfo info = m_androidConfig.gatherCreateAVDInfo(this); if (info.target.isEmpty()) { - m_ui->AVDAddPushButton->setEnabled(true); + enableAvdControls(); return; } @@ -532,29 +571,31 @@ void AndroidSettingsWidget::addAVD() void AndroidSettingsWidget::avdAdded() { - m_ui->AVDAddPushButton->setEnabled(true); AndroidConfig::CreateAvdInfo info = m_futureWatcher.result(); if (!info.error.isEmpty()) { + enableAvdControls(); QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error); return; } - m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices()); - m_ui->AVDTableView->setCurrentIndex(m_AVDModel.indexForAvdName(info.name)); + startUpdateAvd(); + m_lastAddedAvd = info.name; } void AndroidSettingsWidget::removeAVD() { + disableAvdControls(); QString avdName = m_AVDModel.avdName(m_ui->AVDTableView->currentIndex()); if (QMessageBox::question(this, tr("Remove Android Virtual Device"), tr("Remove device \"%1\"? This cannot be undone.").arg(avdName), QMessageBox::Yes | QMessageBox::No) - == QMessageBox::No) + == QMessageBox::No) { + enableAvdControls(); return; + } m_androidConfig.removeAVD(avdName); - m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices()); - avdActivated(m_ui->AVDTableView->currentIndex()); + startUpdateAvd(); } void AndroidSettingsWidget::startAVD() diff --git a/src/plugins/android/androidsettingswidget.h b/src/plugins/android/androidsettingswidget.h index f73b35bfcf1..20a73eae61c 100644 --- a/src/plugins/android/androidsettingswidget.h +++ b/src/plugins/android/androidsettingswidget.h @@ -96,6 +96,7 @@ private slots: void checkGdbFinished(); void showGdbWarningDialog(); + void updateAvds(); private: enum Mode { Sdk = 1, Ndk = 2, Java = 4, All = Sdk | Ndk | Java }; @@ -104,6 +105,9 @@ private: void applyToUi(Mode mode); bool sdkLocationIsValid() const; bool sdkPlatformToolsInstalled() const; + void startUpdateAvd(); + void enableAvdControls(); + void disableAvdControls(); State m_sdkState; State m_ndkState; @@ -118,6 +122,9 @@ private: QFutureWatcher m_futureWatcher; QFutureWatcher> m_checkGdbWatcher; QStringList m_gdbCheckPaths; + + QFutureWatcher> m_virtualDevicesWatcher; + QString m_lastAddedAvd; }; } // namespace Internal diff --git a/src/plugins/android/androidsettingswidget.ui b/src/plugins/android/androidsettingswidget.ui index 7343d334c40..23d09510466 100644 --- a/src/plugins/android/androidsettingswidget.ui +++ b/src/plugins/android/androidsettingswidget.ui @@ -476,74 +476,10 @@ - + - - NDKLocationPathChooser - changed(QString) - AndroidSettingsWidget - ndkLocationEditingFinished() - - - 605 - 143 - - - 352 - 210 - - - - - SDKLocationPathChooser - changed(QString) - AndroidSettingsWidget - sdkLocationEditingFinished() - - - 605 - 82 - - - 352 - 210 - - - - - AntLocationPathChooser - changed(QString) - AndroidSettingsWidget - antLocationEditingFinished() - - - 605 - 315 - - - 352 - 210 - - - - - OpenJDKLocationPathChooser - changed(QString) - AndroidSettingsWidget - openJDKLocationEditingFinished() - - - 605 - 31 - - - 352 - 210 - - - AVDAddPushButton clicked()