forked from qt-creator/qt-creator
Android: read SDK configuration from user editable path
By default, copy the sdk_definitions.json to Qt Creator user resource path. The user can use that to make any updates if desired. Add SdkDownloader instance as a member of AndroidSettingsWidget. Change-Id: Ieabc9c6ddecbe63586f750b26bcf4ca990caee26 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#ifndef ANDROIDSDKDOWNLOADER_H
|
||||
#define ANDROIDSDKDOWNLOADER_H
|
||||
|
||||
#include "androidconfigurations.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QObject>
|
||||
#include <QProgressDialog>
|
||||
@@ -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
|
||||
|
||||
@@ -149,6 +149,7 @@ private:
|
||||
QString m_lastAddedAvd;
|
||||
std::unique_ptr<AndroidAvdManager> m_avdManager;
|
||||
std::unique_ptr<AndroidSdkManager> m_sdkManager;
|
||||
std::unique_ptr<AndroidSdkDownloader> 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<SummaryWidget *>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user