Use Utils::Archive instead of java's jar in AndroidSdkDownloader

The exctraction of the downloaded commandlinetools zip file via java's
jar tool did suddenly not work anymore on Windows. The exit code of
jarExtractProc in AndroidSdkDownloader::extractSdk would be != 0.

Instead of fixing the jar usage, this change replaces it with the
recently added Utils::Archive.

That has the advantage that it preserves the file permissions while
exctracting, so that we can also get rid of setSdkFilesExecPermission.

Another advantage is that the SDK can be extracted even before a jdk
has been selected.

Change-Id: I99cc2aff8e183108eb11dbf96f06557e5b299d56
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Alessandro Portale
2021-12-20 00:09:00 +01:00
parent abe09bfd76
commit 9e2554b660
3 changed files with 19 additions and 60 deletions

View File

@@ -24,13 +24,13 @@
****************************************************************************/
#include "androidsdkdownloader.h"
#include "utils/filepath.h"
#include "utils/qtcprocess.h"
#include <utils/archive.h>
#include <utils/filepath.h>
#include <coreplugin/icore.h>
#include <QCryptographicHash>
#include <QDir>
#include <QDirIterator>
#include <QLoggingCategory>
#include <QStandardPaths>
@@ -61,22 +61,7 @@ void AndroidSdkDownloader::sslErrors(const QList<QSslError> &sslErrors)
}
#endif
static void setSdkFilesExecPermission( const FilePath &sdkExtractPath)
{
const FilePath filePath = sdkExtractPath / "tools";
filePath.iterateDirectory(
[](const FilePath &filePath) {
if (!filePath.fileName().contains('.')) {
QFlags<QFileDevice::Permission> currentPermissions = filePath.permissions();
filePath.setPermissions(currentPermissions | QFileDevice::ExeOwner);
}
return true;
},
{{"*"}, QDir::Files, QDirIterator::Subdirectories});
}
void AndroidSdkDownloader::downloadAndExtractSdk(const FilePath &jdkPath, const FilePath &sdkExtractPath)
void AndroidSdkDownloader::downloadAndExtractSdk(const FilePath &sdkExtractPath)
{
if (m_androidConfig.sdkToolsUrl().isEmpty()) {
logError(tr("The SDK Tools download URL is empty."));
@@ -103,34 +88,16 @@ void AndroidSdkDownloader::downloadAndExtractSdk(const FilePath &jdkPath, const
connect(m_progressDialog, &QProgressDialog::canceled, this, &AndroidSdkDownloader::cancel);
connect(this, &AndroidSdkDownloader::sdkPackageWriteFinished, this, [this, jdkPath, sdkExtractPath]() {
if (extractSdk(jdkPath, sdkExtractPath)) {
setSdkFilesExecPermission(sdkExtractPath);
connect(this, &AndroidSdkDownloader::sdkPackageWriteFinished, this, [this, sdkExtractPath]() {
if (Archive *archive = Archive::unarchive(m_sdkFilename, sdkExtractPath)) {
connect(archive, &Archive::finished, [this, sdkExtractPath](bool success){
if (success)
emit sdkExtracted();
});
}
});
}
bool AndroidSdkDownloader::extractSdk(const FilePath &jdkPath, const FilePath &sdkExtractPath)
{
QDir sdkDir = sdkExtractPath.toDir();
if (!sdkDir.exists()) {
if (!sdkDir.mkpath(".")) {
logError(QString(tr("Could not create the SDK folder %1."))
.arg(sdkExtractPath.toUserOutput()));
return false;
}
}
QtcProcess jarExtractProc;
jarExtractProc.setWorkingDirectory(sdkExtractPath);
FilePath jarCmdPath(jdkPath / "/bin/jar");
jarExtractProc.setCommand({jarCmdPath, {"xf", m_sdkFilename.path()}});
jarExtractProc.runBlocking();
return jarExtractProc.exitCode() ? false : true;
}
bool AndroidSdkDownloader::verifyFileIntegrity()
{
QFile f(m_sdkFilename.toString());
@@ -170,7 +137,7 @@ void AndroidSdkDownloader::logError(const QString &error)
emit sdkDownloaderError(error);
}
QString AndroidSdkDownloader::getSaveFilename(const QUrl &url)
FilePath AndroidSdkDownloader::getSaveFilename(const QUrl &url)
{
QString path = url.path();
QString basename = QFileInfo(path).fileName();
@@ -186,9 +153,8 @@ QString AndroidSdkDownloader::getSaveFilename(const QUrl &url)
basename += QString::number(i);
}
QString fullPath = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)
+ QDir::separator() + basename;
return fullPath;
return FilePath::fromString(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
/ basename;
}
bool AndroidSdkDownloader::saveToDisk(const FilePath &filename, QIODevice *data)
@@ -223,7 +189,7 @@ void AndroidSdkDownloader::downloadFinished(QNetworkReply *reply)
if (isHttpRedirect(reply)) {
cancelWithError(QString(tr("Download from %1 was redirected.")).arg(url.toString()));
} else {
m_sdkFilename = FilePath::fromString(getSaveFilename(url));
m_sdkFilename = getSaveFilename(url);
if (saveToDisk(m_sdkFilename, reply) && verifyFileIntegrity())
emit sdkPackageWriteFinished();
else

View File

@@ -43,7 +43,7 @@ class AndroidSdkDownloader : public QObject
public:
AndroidSdkDownloader();
void downloadAndExtractSdk(const Utils::FilePath &jdkPath, const Utils::FilePath &sdkExtractPath);
void downloadAndExtractSdk(const Utils::FilePath &sdkExtractPath);
static QString dialogTitle();
void cancel();
@@ -54,11 +54,10 @@ signals:
void sdkDownloaderError(const QString &error);
private:
static QString getSaveFilename(const QUrl &url);
static Utils::FilePath getSaveFilename(const QUrl &url);
bool saveToDisk(const Utils::FilePath &filename, QIODevice *data);
static bool isHttpRedirect(QNetworkReply *m_reply);
bool extractSdk(const Utils::FilePath &jdkPath, const Utils::FilePath &sdkExtractPath);
bool verifyFileIntegrity();
void cancelWithError(const QString &error);
void logError(const QString &error);

View File

@@ -712,14 +712,8 @@ void AndroidSettingsWidget::downloadSdk()
.arg(m_ui.SDKLocationPathChooser->filePath().cleanPath().toUserOutput());
auto userInput = QMessageBox::information(this, AndroidSdkDownloader::dialogTitle(),
message, QMessageBox::Yes | QMessageBox::No);
if (userInput == QMessageBox::Yes) {
if (m_androidSummary->rowsOk({JavaPathExistsAndWritableRow})) {
auto javaPath = m_ui.OpenJDKLocationPathChooser->filePath();
m_sdkDownloader.downloadAndExtractSdk(
javaPath,
m_ui.SDKLocationPathChooser->filePath().cleanPath());
}
}
if (userInput == QMessageBox::Yes)
m_sdkDownloader.downloadAndExtractSdk(m_ui.SDKLocationPathChooser->filePath().cleanPath());
}
// AndroidSettingsPage