Commit ab372deb authored by Daniel Teske's avatar Daniel Teske
Browse files

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: default avatarBogDan Vatra <bogdan@kde.org>
parent 8a29109f
...@@ -600,12 +600,22 @@ bool AndroidConfig::removeAVD(const QString &name) const ...@@ -600,12 +600,22 @@ bool AndroidConfig::removeAVD(const QString &name) const
return !proc.exitCode(); return !proc.exitCode();
} }
QFuture<QVector<AndroidDeviceInfo>> AndroidConfig::androidVirtualDevicesFuture()
{
return QtConcurrent::run(&AndroidConfig::androidVirtualDevicesImpl, androidToolPath(), androidToolEnvironment());
}
QVector<AndroidDeviceInfo> AndroidConfig::androidVirtualDevices() const QVector<AndroidDeviceInfo> AndroidConfig::androidVirtualDevices() const
{
return androidVirtualDevicesImpl(androidToolPath(), androidToolEnvironment());
}
QVector<AndroidDeviceInfo> AndroidConfig::androidVirtualDevicesImpl(const Utils::FileName &androidTool, const Utils::Environment &environment)
{ {
QVector<AndroidDeviceInfo> devices; QVector<AndroidDeviceInfo> devices;
QProcess proc; QProcess proc;
proc.setProcessEnvironment(androidToolEnvironment().toProcessEnvironment()); proc.setProcessEnvironment(environment.toProcessEnvironment());
proc.start(androidToolPath().toString(), proc.start(androidTool.toString(),
QStringList() << QLatin1String("list") << QLatin1String("avd")); // list available AVDs QStringList() << QLatin1String("list") << QLatin1String("avd")); // list available AVDs
if (!proc.waitForFinished(5000)) { if (!proc.waitForFinished(5000)) {
proc.terminate(); proc.terminate();
......
...@@ -146,7 +146,10 @@ public: ...@@ -146,7 +146,10 @@ public:
bool removeAVD(const QString &name) const; bool removeAVD(const QString &name) const;
QVector<AndroidDeviceInfo> connectedDevices(QString *error = 0) const; QVector<AndroidDeviceInfo> connectedDevices(QString *error = 0) const;
QFuture<QVector<AndroidDeviceInfo> > androidVirtualDevicesFuture();
QVector<AndroidDeviceInfo> androidVirtualDevices() const; QVector<AndroidDeviceInfo> androidVirtualDevices() const;
QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const; QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const;
bool startAVDAsync(const QString &avdName) const; bool startAVDAsync(const QString &avdName) const;
QString findAvd(int apiLevel, const QString &cpuAbi) const; QString findAvd(int apiLevel, const QString &cpuAbi) const;
...@@ -165,6 +168,7 @@ public: ...@@ -165,6 +168,7 @@ public:
SdkPlatform highestAndroidSdk() const; SdkPlatform highestAndroidSdk() const;
private: private:
static CreateAvdInfo createAVDImpl(CreateAvdInfo info, Utils::FileName androidToolPath, Utils::Environment env); static CreateAvdInfo createAVDImpl(CreateAvdInfo info, Utils::FileName androidToolPath, Utils::Environment env);
static QVector<AndroidDeviceInfo> androidVirtualDevicesImpl(const Utils::FileName &androidTool, const Utils::Environment &environment);
Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const; Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const;
Utils::FileName openJDKBinPath() const; Utils::FileName openJDKBinPath() const;
......
...@@ -170,7 +170,6 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent) ...@@ -170,7 +170,6 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
m_ui->DataPartitionSizeSpinBox->setValue(m_androidConfig.partitionSize()); m_ui->DataPartitionSizeSpinBox->setValue(m_androidConfig.partitionSize());
m_ui->CreateKitCheckBox->setChecked(m_androidConfig.automaticKitCreation()); m_ui->CreateKitCheckBox->setChecked(m_androidConfig.automaticKitCreation());
m_ui->AVDTableView->setModel(&m_AVDModel); m_ui->AVDTableView->setModel(&m_AVDModel);
m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices());
m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
...@@ -180,11 +179,20 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent) ...@@ -180,11 +179,20 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
connect(m_ui->gdbWarningLabel, SIGNAL(linkActivated(QString)), connect(m_ui->gdbWarningLabel, SIGNAL(linkActivated(QString)),
this, SLOT(showGdbWarningDialog())); this, SLOT(showGdbWarningDialog()));
connect(&m_virtualDevicesWatcher, SIGNAL(finished()),
this, SLOT(updateAvds()));
check(All); check(All);
applyToUi(All); applyToUi(All);
connect(&m_futureWatcher, SIGNAL(finished()), connect(&m_futureWatcher, SIGNAL(finished()),
this, SLOT(avdAdded())); 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() AndroidSettingsWidget::~AndroidSettingsWidget()
...@@ -397,10 +405,41 @@ void AndroidSettingsWidget::applyToUi(AndroidSettingsWidget::Mode mode) ...@@ -397,10 +405,41 @@ void AndroidSettingsWidget::applyToUi(AndroidSettingsWidget::Mode mode)
m_ui->AVDManagerFrame->setEnabled(false); 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 bool AndroidSettingsWidget::sdkLocationIsValid() const
{ {
Utils::FileName androidExe = m_androidConfig.sdkLocation(); Utils::FileName androidExe = m_androidConfig.sdkLocation();
...@@ -519,11 +558,11 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl() ...@@ -519,11 +558,11 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl()
void AndroidSettingsWidget::addAVD() void AndroidSettingsWidget::addAVD()
{ {
m_ui->AVDAddPushButton->setEnabled(false); disableAvdControls();
AndroidConfig::CreateAvdInfo info = m_androidConfig.gatherCreateAVDInfo(this); AndroidConfig::CreateAvdInfo info = m_androidConfig.gatherCreateAVDInfo(this);
if (info.target.isEmpty()) { if (info.target.isEmpty()) {
m_ui->AVDAddPushButton->setEnabled(true); enableAvdControls();
return; return;
} }
...@@ -532,29 +571,31 @@ void AndroidSettingsWidget::addAVD() ...@@ -532,29 +571,31 @@ void AndroidSettingsWidget::addAVD()
void AndroidSettingsWidget::avdAdded() void AndroidSettingsWidget::avdAdded()
{ {
m_ui->AVDAddPushButton->setEnabled(true);
AndroidConfig::CreateAvdInfo info = m_futureWatcher.result(); AndroidConfig::CreateAvdInfo info = m_futureWatcher.result();
if (!info.error.isEmpty()) { if (!info.error.isEmpty()) {
enableAvdControls();
QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error); QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
return; return;
} }
m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices()); startUpdateAvd();
m_ui->AVDTableView->setCurrentIndex(m_AVDModel.indexForAvdName(info.name)); m_lastAddedAvd = info.name;
} }
void AndroidSettingsWidget::removeAVD() void AndroidSettingsWidget::removeAVD()
{ {
disableAvdControls();
QString avdName = m_AVDModel.avdName(m_ui->AVDTableView->currentIndex()); QString avdName = m_AVDModel.avdName(m_ui->AVDTableView->currentIndex());
if (QMessageBox::question(this, tr("Remove Android Virtual Device"), if (QMessageBox::question(this, tr("Remove Android Virtual Device"),
tr("Remove device \"%1\"? This cannot be undone.").arg(avdName), tr("Remove device \"%1\"? This cannot be undone.").arg(avdName),
QMessageBox::Yes | QMessageBox::No) QMessageBox::Yes | QMessageBox::No)
== QMessageBox::No) == QMessageBox::No) {
enableAvdControls();
return; return;
}
m_androidConfig.removeAVD(avdName); m_androidConfig.removeAVD(avdName);
m_AVDModel.setAvdList(m_androidConfig.androidVirtualDevices()); startUpdateAvd();
avdActivated(m_ui->AVDTableView->currentIndex());
} }
void AndroidSettingsWidget::startAVD() void AndroidSettingsWidget::startAVD()
......
...@@ -96,6 +96,7 @@ private slots: ...@@ -96,6 +96,7 @@ private slots:
void checkGdbFinished(); void checkGdbFinished();
void showGdbWarningDialog(); void showGdbWarningDialog();
void updateAvds();
private: private:
enum Mode { Sdk = 1, Ndk = 2, Java = 4, All = Sdk | Ndk | Java }; enum Mode { Sdk = 1, Ndk = 2, Java = 4, All = Sdk | Ndk | Java };
...@@ -104,6 +105,9 @@ private: ...@@ -104,6 +105,9 @@ private:
void applyToUi(Mode mode); void applyToUi(Mode mode);
bool sdkLocationIsValid() const; bool sdkLocationIsValid() const;
bool sdkPlatformToolsInstalled() const; bool sdkPlatformToolsInstalled() const;
void startUpdateAvd();
void enableAvdControls();
void disableAvdControls();
State m_sdkState; State m_sdkState;
State m_ndkState; State m_ndkState;
...@@ -118,6 +122,9 @@ private: ...@@ -118,6 +122,9 @@ private:
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher; QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher;
QFutureWatcher<QPair<QStringList, bool>> m_checkGdbWatcher; QFutureWatcher<QPair<QStringList, bool>> m_checkGdbWatcher;
QStringList m_gdbCheckPaths; QStringList m_gdbCheckPaths;
QFutureWatcher<QVector<AndroidDeviceInfo>> m_virtualDevicesWatcher;
QString m_lastAddedAvd;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -476,74 +476,10 @@ ...@@ -476,74 +476,10 @@
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="android.qrc"/>
<include location="../coreplugin/core.qrc"/> <include location="../coreplugin/core.qrc"/>
<include location="android.qrc"/>
</resources> </resources>
<connections> <connections>
<connection>
<sender>NDKLocationPathChooser</sender>
<signal>changed(QString)</signal>
<receiver>AndroidSettingsWidget</receiver>
<slot>ndkLocationEditingFinished()</slot>
<hints>
<hint type="sourcelabel">
<x>605</x>
<y>143</y>
</hint>
<hint type="destinationlabel">
<x>352</x>
<y>210</y>
</hint>
</hints>
</connection>
<connection>
<sender>SDKLocationPathChooser</sender>
<signal>changed(QString)</signal>
<receiver>AndroidSettingsWidget</receiver>
<slot>sdkLocationEditingFinished()</slot>
<hints>
<hint type="sourcelabel">
<x>605</x>
<y>82</y>
</hint>
<hint type="destinationlabel">
<x>352</x>
<y>210</y>
</hint>
</hints>
</connection>
<connection>
<sender>AntLocationPathChooser</sender>
<signal>changed(QString)</signal>
<receiver>AndroidSettingsWidget</receiver>
<slot>antLocationEditingFinished()</slot>
<hints>
<hint type="sourcelabel">
<x>605</x>
<y>315</y>
</hint>
<hint type="destinationlabel">
<x>352</x>
<y>210</y>
</hint>
</hints>
</connection>
<connection>
<sender>OpenJDKLocationPathChooser</sender>
<signal>changed(QString)</signal>
<receiver>AndroidSettingsWidget</receiver>
<slot>openJDKLocationEditingFinished()</slot>
<hints>
<hint type="sourcelabel">
<x>605</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>352</x>
<y>210</y>
</hint>
</hints>
</connection>
<connection> <connection>
<sender>AVDAddPushButton</sender> <sender>AVDAddPushButton</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment