diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index d4f2de98628..8126991a08a 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -286,13 +286,27 @@ void AndroidConfig::save(QSettings &settings) const void AndroidConfig::parseDependenciesJson() { + QString sdkConfigUserFile(Core::ICore::userResourcePath() + JsonFilePath); QString sdkConfigFile(Core::ICore::resourcePath() + JsonFilePath); - QFile jsonFile(sdkConfigFile); - if (!jsonFile.open(QIODevice::ReadOnly)) - qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(sdkConfigFile)); - QJsonDocument loadDoc(QJsonDocument::fromJson(jsonFile.readAll())); - QJsonObject jsonObject = loadDoc.object(); + if (!QFile::exists(sdkConfigUserFile)) { + QDir(QFileInfo(sdkConfigUserFile).absolutePath()).mkpath("."); + QFile::copy(sdkConfigFile, sdkConfigUserFile); + } + + if (QFileInfo(sdkConfigFile).lastModified() > QFileInfo(sdkConfigUserFile).lastModified()) { + QFile::remove(sdkConfigUserFile + ".old"); + QFile::rename(sdkConfigUserFile, sdkConfigUserFile + ".old"); + QFile::copy(sdkConfigFile, sdkConfigUserFile); + } + + QFile jsonFile(sdkConfigUserFile); + if (!jsonFile.open(QIODevice::ReadOnly)) { + qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(jsonFile.fileName())); + return; + } + + QJsonObject jsonObject = QJsonDocument::fromJson(jsonFile.readAll()).object(); if (jsonObject.contains(CommonKey) && jsonObject[CommonKey].isObject()) { QJsonObject commonObject = jsonObject[CommonKey].toObject(); diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index fdefe3ea35d..83ea197f779 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -42,9 +42,9 @@ namespace Internal { * @class SdkDownloader * @brief Download Android SDK tools package from within Qt Creator. */ -AndroidSdkDownloader::AndroidSdkDownloader(const QUrl &sdkUrl, const QByteArray &sha256) : - m_sdkUrl(sdkUrl), m_sha256(sha256) +AndroidSdkDownloader::AndroidSdkDownloader() { + m_androidConfig = AndroidConfigurations::currentConfig(); connect(&m_manager, &QNetworkAccessManager::finished, this, &AndroidSdkDownloader::downloadFinished); } @@ -73,12 +73,12 @@ static void setSdkFilesExecPermission( const QString &sdkExtractPath) void AndroidSdkDownloader::downloadAndExtractSdk(const QString &jdkPath, const QString &sdkExtractPath) { - if (m_sdkUrl.isEmpty()) { + if (m_androidConfig.sdkToolsUrl().isEmpty()) { logError(tr("The SDK Tools download URL is empty.")); return; } - QNetworkRequest request(m_sdkUrl); + QNetworkRequest request(m_androidConfig.sdkToolsUrl()); m_reply = m_manager.get(request); #if QT_CONFIG(ssl) @@ -131,7 +131,7 @@ bool AndroidSdkDownloader::verifyFileIntegrity() if (f.open(QFile::ReadOnly)) { QCryptographicHash hash(QCryptographicHash::Sha256); if (hash.addData(&f)) { - return hash.result() == m_sha256; + return hash.result() == m_androidConfig.getSdkToolsSha256(); } } return false; diff --git a/src/plugins/android/androidsdkdownloader.h b/src/plugins/android/androidsdkdownloader.h index 7cb1b042026..f8942b0a3dc 100644 --- a/src/plugins/android/androidsdkdownloader.h +++ b/src/plugins/android/androidsdkdownloader.h @@ -26,6 +26,8 @@ #ifndef ANDROIDSDKDOWNLOADER_H #define ANDROIDSDKDOWNLOADER_H +#include "androidconfigurations.h" + #include #include #include @@ -38,7 +40,7 @@ class AndroidSdkDownloader : public QObject Q_OBJECT public: - AndroidSdkDownloader(const QUrl &sdkUrl, const QByteArray &sha256); + AndroidSdkDownloader(); void downloadAndExtractSdk(const QString &jdkPath, const QString &sdkExtractPath); static QString dialogTitle(); @@ -68,8 +70,7 @@ private: QNetworkReply *m_reply = nullptr; QString m_sdkFilename; QProgressDialog *m_progressDialog = nullptr; - QUrl m_sdkUrl; - QByteArray m_sha256; + AndroidConfig m_androidConfig; }; } // Internal diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 22aad57a88a..bf40091db95 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -149,6 +149,7 @@ private: QString m_lastAddedAvd; std::unique_ptr m_avdManager; std::unique_ptr m_sdkManager; + std::unique_ptr m_sdkDownloader; bool m_isInitialReloadDone = false; }; @@ -405,7 +406,8 @@ AndroidSettingsWidget::AndroidSettingsWidget() : m_ui(new Ui_AndroidSettingsWidget), m_androidConfig(AndroidConfigurations::currentConfig()), m_avdManager(new AndroidAvdManager(m_androidConfig)), - m_sdkManager(new AndroidSdkManager(m_androidConfig)) + m_sdkManager(new AndroidSdkManager(m_androidConfig)), + m_sdkDownloader(new AndroidSdkDownloader()) { m_ui->setupUi(this); m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, m_sdkManager.get(), @@ -498,6 +500,13 @@ AndroidSettingsWidget::AndroidSettingsWidget() m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon); m_ui->downloadOpenSSLPrebuiltLibs->setIcon(downloadIcon); m_ui->sdkToolsAutoDownloadButton->setIcon(Utils::Icons::RELOAD.icon()); + m_ui->sdkToolsAutoDownloadButton->setToolTip(tr( + "Automatically download Android SDK Tools to selected location.\n\n" + "If the selected path contains no valid SDK Tools, the SDK Tools package " + "is downloaded from %1, and extracted to the selected path.\n" + "After the SDK Tools are properly set up, you are prompted to install " + "any essential packages required for Qt to build for Android.\n") + .arg(m_androidConfig.sdkToolsUrl().toString())); connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged, this, &AndroidSettingsWidget::onSdkPathChanged); @@ -545,18 +554,25 @@ AndroidSettingsWidget::AndroidSettingsWidget() connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked, this, &AndroidSettingsWidget::openOpenJDKDownloadUrl); // Validate SDK again after any change in SDK packages. - connect(m_sdkManager.get(), - &AndroidSdkManager::packageReloadFinished, - this, - &AndroidSettingsWidget::validateSdk); - connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked, this, [this]() { - if (sdkToolsOk()) { - QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), - tr("The selected path already has a valid SDK Tools package.")); - validateSdk(); - return; - } - downloadSdk(); + connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished, + this, &AndroidSettingsWidget::validateSdk); + connect(m_ui->sdkToolsAutoDownloadButton, &QAbstractButton::clicked, + this, &AndroidSettingsWidget::downloadSdk); + connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkDownloaderError, this, [this](const QString &error) { + QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error); + }); + connect(m_sdkDownloader.get(), &AndroidSdkDownloader::sdkExtracted, this, [this]() { + m_sdkManager->reloadPackages(true); + updateUI(); + apply(); + + QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection; + *openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished, + this, [this, openSslOneShot]() { + QObject::disconnect(*openSslOneShot); + downloadOpenSslRepo(true); + delete openSslOneShot; + }); }); } @@ -933,6 +949,13 @@ void AndroidSettingsWidget::manageAVD() void AndroidSettingsWidget::downloadSdk() { + if (sdkToolsOk()) { + QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), + tr("The selected path already has a valid SDK Tools package.")); + validateSdk(); + return; + } + QString message(tr("Download and install Android SDK Tools to: %1?") .arg(QDir::toNativeSeparators(m_ui->SDKLocationPathChooser->rawPath()))); auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(), @@ -941,31 +964,8 @@ void AndroidSettingsWidget::downloadSdk() auto javaSummaryWidget = static_cast(m_ui->javaDetailsWidget->widget()); if (javaSummaryWidget->allRowsOk()) { auto javaPath = Utils::FilePath::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath()); - AndroidSdkDownloader *sdkDownloader = new AndroidSdkDownloader( - m_androidConfig.sdkToolsUrl(), - m_androidConfig.getSdkToolsSha256()); - sdkDownloader->downloadAndExtractSdk(javaPath.toString(), + m_sdkDownloader->downloadAndExtractSdk(javaPath.toString(), m_ui->SDKLocationPathChooser->path()); - - connect(sdkDownloader, &AndroidSdkDownloader::sdkExtracted, this, [this]() { - m_sdkManager->reloadPackages(true); - updateUI(); - apply(); - - QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection; - *openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished, - this, [this, openSslOneShot]() { - QObject::disconnect(*openSslOneShot); - downloadOpenSslRepo(true); - delete openSslOneShot; - }); - }); - - auto showErrorDialog = [this](const QString &error) { - QMessageBox::warning(this, AndroidSdkDownloader::dialogTitle(), error); - }; - - connect(sdkDownloader, &AndroidSdkDownloader::sdkDownloaderError, this, showErrorDialog); } } }