forked from qt-creator/qt-creator
Android: Enable common arguments for SDK manager command
Task-number: QTCREATORBUG-18978 Change-Id: I9f3e2b16a77ff949268960d2b5c5aa1896fa3770 Reviewed-by: BogDan Vatra <bogdan@kdab.com> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
@@ -87,6 +87,7 @@ namespace {
|
||||
|
||||
const QLatin1String SettingsGroup("AndroidConfigurations");
|
||||
const QLatin1String SDKLocationKey("SDKLocation");
|
||||
const QLatin1String SDKManagerToolArgsKey("SDKManagerToolArgs");
|
||||
const QLatin1String NDKLocationKey("NDKLocation");
|
||||
const QLatin1String OpenJDKLocationKey("OpenJDKLocation");
|
||||
const QLatin1String KeystoreLocationKey("KeystoreLocation");
|
||||
@@ -246,6 +247,7 @@ void AndroidConfig::load(const QSettings &settings)
|
||||
// user settings
|
||||
m_partitionSize = settings.value(PartitionSizeKey, 1024).toInt();
|
||||
m_sdkLocation = FileName::fromString(settings.value(SDKLocationKey).toString());
|
||||
m_sdkManagerToolArgs = settings.value(SDKManagerToolArgsKey).toStringList();
|
||||
m_ndkLocation = FileName::fromString(settings.value(NDKLocationKey).toString());
|
||||
m_openJDKLocation = FileName::fromString(settings.value(OpenJDKLocationKey).toString());
|
||||
m_keystoreLocation = FileName::fromString(settings.value(KeystoreLocationKey).toString());
|
||||
@@ -261,6 +263,7 @@ void AndroidConfig::load(const QSettings &settings)
|
||||
&& settings.value(changeTimeStamp).toInt() != QFileInfo(sdkSettingsFileName()).lastModified().toMSecsSinceEpoch() / 1000) {
|
||||
// persisten settings
|
||||
m_sdkLocation = FileName::fromString(reader.restoreValue(SDKLocationKey, m_sdkLocation.toString()).toString());
|
||||
m_sdkManagerToolArgs = reader.restoreValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs).toStringList();
|
||||
m_ndkLocation = FileName::fromString(reader.restoreValue(NDKLocationKey, m_ndkLocation.toString()).toString());
|
||||
m_openJDKLocation = FileName::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString());
|
||||
m_keystoreLocation = FileName::fromString(reader.restoreValue(KeystoreLocationKey, m_keystoreLocation.toString()).toString());
|
||||
@@ -283,6 +286,7 @@ void AndroidConfig::save(QSettings &settings) const
|
||||
|
||||
// user settings
|
||||
settings.setValue(SDKLocationKey, m_sdkLocation.toString());
|
||||
settings.setValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs);
|
||||
settings.setValue(NDKLocationKey, m_ndkLocation.toString());
|
||||
settings.setValue(OpenJDKLocationKey, m_openJDKLocation.toString());
|
||||
settings.setValue(KeystoreLocationKey, m_keystoreLocation.toString());
|
||||
@@ -727,6 +731,17 @@ QVersionNumber AndroidConfig::buildToolsVersion() const
|
||||
return maxVersion;
|
||||
}
|
||||
|
||||
|
||||
QStringList AndroidConfig::sdkManagerToolArgs() const
|
||||
{
|
||||
return m_sdkManagerToolArgs;
|
||||
}
|
||||
|
||||
void AndroidConfig::setSdkManagerToolArgs(const QStringList &args)
|
||||
{
|
||||
m_sdkManagerToolArgs = args;
|
||||
}
|
||||
|
||||
FileName AndroidConfig::ndkLocation() const
|
||||
{
|
||||
return m_ndkLocation;
|
||||
|
@@ -100,6 +100,8 @@ public:
|
||||
void setSdkLocation(const Utils::FileName &sdkLocation);
|
||||
QVersionNumber sdkToolsVersion() const;
|
||||
QVersionNumber buildToolsVersion() const;
|
||||
QStringList sdkManagerToolArgs() const;
|
||||
void setSdkManagerToolArgs(const QStringList &args);
|
||||
|
||||
Utils::FileName ndkLocation() const;
|
||||
QVersionNumber ndkVersion() const;
|
||||
@@ -166,6 +168,7 @@ private:
|
||||
void updateNdkInformation() const;
|
||||
|
||||
Utils::FileName m_sdkLocation;
|
||||
QStringList m_sdkManagerToolArgs;
|
||||
Utils::FileName m_ndkLocation;
|
||||
Utils::FileName m_openJDKLocation;
|
||||
Utils::FileName m_keystoreLocation;
|
||||
|
@@ -24,6 +24,7 @@
|
||||
****************************************************************************/
|
||||
#include "androidsdkmanager.h"
|
||||
|
||||
#include "androidconstants.h"
|
||||
#include "androidmanager.h"
|
||||
#include "androidtoolmanager.h"
|
||||
|
||||
@@ -31,7 +32,6 @@
|
||||
#include "utils/qtcassert.h"
|
||||
#include "utils/runextensions.h"
|
||||
#include "utils/synchronousprocess.h"
|
||||
#include "utils/environment.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QLoggingCategory>
|
||||
@@ -52,6 +52,7 @@ const QVersionNumber sdkManagerIntroVersion(25, 3 ,0);
|
||||
const char installLocationKey[] = "Installed Location:";
|
||||
const char revisionKey[] = "Version:";
|
||||
const char descriptionKey[] = "Description:";
|
||||
const char commonArgsKey[] = "Common Arguments:";
|
||||
|
||||
const int sdkManagerCmdTimeoutS = 60;
|
||||
const int sdkManagerOperationTimeoutS = 600;
|
||||
@@ -178,6 +179,7 @@ public:
|
||||
const AndroidSdkPackageList &allPackages(bool forceUpdate = false);
|
||||
void refreshSdkPackages(bool forceReload = false);
|
||||
|
||||
void parseCommonArguments(QFutureInterface<QString> &fi);
|
||||
void updateInstalled(SdkCmdFutureInterface &fi);
|
||||
void update(SdkCmdFutureInterface &fi, const QStringList &install,
|
||||
const QStringList &uninstall);
|
||||
@@ -335,6 +337,11 @@ bool AndroidSdkManager::isBusy() const
|
||||
return m_d->m_activeOperation && !m_d->m_activeOperation->isFinished();
|
||||
}
|
||||
|
||||
QFuture<QString> AndroidSdkManager::availableArguments() const
|
||||
{
|
||||
return Utils::runAsync(&AndroidSdkManagerPrivate::parseCommonArguments, m_d.get());
|
||||
}
|
||||
|
||||
QFuture<AndroidSdkManager::OperationOutput> AndroidSdkManager::updateAll()
|
||||
{
|
||||
if (isBusy()) {
|
||||
@@ -663,7 +670,6 @@ AndroidSdkManagerPrivate::AndroidSdkManagerPrivate(AndroidSdkManager &sdkManager
|
||||
m_sdkManager(sdkManager),
|
||||
m_config(config)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AndroidSdkManagerPrivate::~AndroidSdkManagerPrivate()
|
||||
@@ -709,8 +715,9 @@ void AndroidSdkManagerPrivate::reloadSdkPackages()
|
||||
m_allPackages = Utils::transform(toolManager.availableSdkPlatforms(), toAndroidSdkPackages);
|
||||
} else {
|
||||
QString packageListing;
|
||||
if (sdkManagerCommand(m_config.sdkManagerToolPath(), QStringList({"--list", "--verbose"}),
|
||||
&packageListing)) {
|
||||
QStringList args({"--list", "--verbose"});
|
||||
args << m_config.sdkManagerToolArgs();
|
||||
if (sdkManagerCommand(m_config.sdkManagerToolPath(), args, &packageListing)) {
|
||||
SdkManagerOutputParser parser(m_allPackages);
|
||||
parser.parsePackageListing(packageListing);
|
||||
}
|
||||
@@ -736,6 +743,7 @@ void AndroidSdkManagerPrivate::updateInstalled(SdkCmdFutureInterface &fi)
|
||||
"Updating installed packages.");
|
||||
fi.reportResult(result);
|
||||
QStringList args("--update");
|
||||
args << m_config.sdkManagerToolArgs();
|
||||
if (!fi.isCanceled())
|
||||
sdkManagerCommand(m_config.sdkManagerToolPath(), args, m_sdkManager, fi, result, 100);
|
||||
else
|
||||
@@ -785,13 +793,17 @@ void AndroidSdkManagerPrivate::update(SdkCmdFutureInterface &fi, const QStringLi
|
||||
// Uninstall packages
|
||||
for (const QString &sdkStylePath : uninstall) {
|
||||
// Uninstall operations are not interptible. We don't want to leave half uninstalled.
|
||||
if (doOperation(sdkStylePath, {"--uninstall", sdkStylePath}, false))
|
||||
QStringList args;
|
||||
args << "--uninstall" << sdkStylePath << m_config.sdkManagerToolArgs();
|
||||
if (doOperation(sdkStylePath, args, false))
|
||||
break;
|
||||
}
|
||||
|
||||
// Install packages
|
||||
for (const QString &sdkStylePath : install) {
|
||||
if (doOperation(sdkStylePath, {sdkStylePath}, true))
|
||||
QStringList args(sdkStylePath);
|
||||
args << m_config.sdkManagerToolArgs();
|
||||
if (doOperation(sdkStylePath, args, true))
|
||||
break;
|
||||
}
|
||||
fi.setProgressValue(100);
|
||||
@@ -805,6 +817,25 @@ void AndroidSdkManagerPrivate::addWatcher(const QFuture<AndroidSdkManager::Opera
|
||||
m_activeOperation->setFuture(future);
|
||||
}
|
||||
|
||||
void AndroidSdkManagerPrivate::parseCommonArguments(QFutureInterface<QString> &fi)
|
||||
{
|
||||
QString argumentDetails;
|
||||
QString output;
|
||||
sdkManagerCommand(m_config.sdkManagerToolPath(), QStringList("--help"), &output);
|
||||
bool foundTag = false;
|
||||
for (const QString& line : output.split('\n')) {
|
||||
if (fi.isCanceled())
|
||||
break;
|
||||
if (foundTag)
|
||||
argumentDetails.append(line + "\n");
|
||||
else if (line.startsWith(commonArgsKey))
|
||||
foundTag = true;
|
||||
}
|
||||
|
||||
if (!fi.isCanceled())
|
||||
fi.reportResult(argumentDetails);
|
||||
}
|
||||
|
||||
void AndroidSdkManagerPrivate::clearPackages()
|
||||
{
|
||||
for (AndroidSdkPackage *p : m_allPackages)
|
||||
|
@@ -73,8 +73,9 @@ public:
|
||||
AndroidSdkPackage::PackageState state
|
||||
= AndroidSdkPackage::Installed);
|
||||
void reloadPackages(bool forceReload = false);
|
||||
|
||||
bool isBusy() const;
|
||||
|
||||
QFuture<QString> availableArguments() const;
|
||||
QFuture<OperationOutput> updateAll();
|
||||
QFuture<OperationOutput> update(const QStringList &install, const QStringList &uninstall);
|
||||
|
||||
|
@@ -26,13 +26,18 @@
|
||||
|
||||
#include "ui_androidsdkmanagerwidget.h"
|
||||
#include "androidconfigurations.h"
|
||||
#include "androidsdkmanager.h"
|
||||
#include "androidsdkmodel.h"
|
||||
|
||||
#include "utils/runextensions.h"
|
||||
#include "utils/outputformatter.h"
|
||||
#include "utils/runextensions.h"
|
||||
#include "utils/qtcassert.h"
|
||||
#include "utils/utilsicons.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
@@ -47,6 +52,21 @@ namespace Internal {
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
class OptionsDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
OptionsDialog(AndroidSdkManager *sdkManager, const QStringList &args,
|
||||
QWidget *parent = nullptr);
|
||||
~OptionsDialog();
|
||||
|
||||
QStringList sdkManagerArguments() const;
|
||||
|
||||
private:
|
||||
QPlainTextEdit *argumentDetailsEdit;
|
||||
QLineEdit *argumentsEdit;
|
||||
QFuture<QString> m_optionsFuture;
|
||||
};
|
||||
|
||||
class PackageFilterModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
@@ -59,7 +79,7 @@ private:
|
||||
AndroidSdkPackage::PackageState m_packageState = AndroidSdkPackage::AnyValidState;
|
||||
};
|
||||
|
||||
AndroidSdkManagerWidget::AndroidSdkManagerWidget(const AndroidConfig &config,
|
||||
AndroidSdkManagerWidget::AndroidSdkManagerWidget(AndroidConfig &config,
|
||||
AndroidSdkManager *sdkManager, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_androidConfig(config),
|
||||
@@ -67,6 +87,7 @@ AndroidSdkManagerWidget::AndroidSdkManagerWidget(const AndroidConfig &config,
|
||||
m_sdkModel(new AndroidSdkModel(m_sdkManager, this)),
|
||||
m_ui(new Ui::AndroidSdkManagerWidget)
|
||||
{
|
||||
QTC_CHECK(sdkManager);
|
||||
m_ui->setupUi(this);
|
||||
m_ui->warningLabel->setElideMode(Qt::ElideRight);
|
||||
m_ui->warningIconLabel->setPixmap(Utils::Icons::WARNING.pixmap());
|
||||
@@ -128,6 +149,8 @@ AndroidSdkManagerWidget::AndroidSdkManagerWidget(const AndroidConfig &config,
|
||||
&AndroidSdkManagerWidget::onCancel);
|
||||
connect(m_ui->nativeSdkManagerButton, &QPushButton::clicked,
|
||||
this, &AndroidSdkManagerWidget::onNativeSdkManager);
|
||||
connect(m_ui->optionsButton, &QPushButton::clicked,
|
||||
this, &AndroidSdkManagerWidget::onSdkManagerOptions);
|
||||
}
|
||||
|
||||
AndroidSdkManagerWidget::~AndroidSdkManagerWidget()
|
||||
@@ -147,6 +170,7 @@ void AndroidSdkManagerWidget::setSdkManagerControlsEnabled(bool enable)
|
||||
m_ui->warningLabel->setVisible(!enable);
|
||||
m_ui->packagesView->setEnabled(enable);
|
||||
m_ui->updateInstalledButton->setEnabled(enable);
|
||||
m_ui->optionsButton->setEnabled(enable);
|
||||
}
|
||||
|
||||
void AndroidSdkManagerWidget::onApplyButton()
|
||||
@@ -323,6 +347,18 @@ AndroidSdkManagerWidget::View AndroidSdkManagerWidget::currentView() const
|
||||
return m_ui->viewStack->currentWidget() == m_ui->packagesStack ? PackageListing : Operations;
|
||||
}
|
||||
|
||||
void AndroidSdkManagerWidget::onSdkManagerOptions()
|
||||
{
|
||||
OptionsDialog dlg(m_sdkManager, m_androidConfig.sdkManagerToolArgs(), this);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
QStringList arguments = dlg.sdkManagerArguments();
|
||||
if (arguments != m_androidConfig.sdkManagerToolArgs()) {
|
||||
m_androidConfig.setSdkManagerToolArgs(arguments);
|
||||
m_sdkManager->reloadPackages(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PackageFilterModel::PackageFilterModel(AndroidSdkModel *sdkModel) :
|
||||
QSortFilterProxyModel(sdkModel)
|
||||
{
|
||||
@@ -360,5 +396,54 @@ bool PackageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
||||
return showTopLevel || (packageState(srcIndex) & m_packageState);
|
||||
}
|
||||
|
||||
OptionsDialog::OptionsDialog(AndroidSdkManager *sdkManager, const QStringList &args,
|
||||
QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QTC_CHECK(sdkManager);
|
||||
resize(800, 480);
|
||||
setWindowTitle(tr("SDK Manager Arguments"));
|
||||
|
||||
argumentDetailsEdit = new QPlainTextEdit(this);
|
||||
argumentDetailsEdit->setReadOnly(true);
|
||||
|
||||
auto populateOptions = [this](const QString& options) {
|
||||
if (options.isEmpty()) {
|
||||
argumentDetailsEdit->setPlainText(tr("Cannot load available arguments for "
|
||||
"\"sdkmanager\" command."));
|
||||
} else {
|
||||
argumentDetailsEdit->setPlainText(options);
|
||||
}
|
||||
};
|
||||
m_optionsFuture = sdkManager->availableArguments();
|
||||
Utils::onResultReady(m_optionsFuture, populateOptions);
|
||||
|
||||
auto dialogButtons = new QDialogButtonBox(this);
|
||||
dialogButtons->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
|
||||
connect(dialogButtons, &QDialogButtonBox::accepted, this, &OptionsDialog::accept);
|
||||
connect(dialogButtons, &QDialogButtonBox::rejected, this, &OptionsDialog::reject);
|
||||
|
||||
argumentsEdit = new QLineEdit(this);
|
||||
argumentsEdit->setText(args.join(" "));
|
||||
|
||||
auto gridLayout = new QGridLayout(this);
|
||||
gridLayout->addWidget(new QLabel(tr("SDK manager arguments:"), this), 0, 0, 1, 1);
|
||||
gridLayout->addWidget(argumentsEdit, 0, 1, 1, 1);
|
||||
gridLayout->addWidget(new QLabel(tr("Available arguments:"), this), 1, 0, 1, 2);
|
||||
gridLayout->addWidget(argumentDetailsEdit, 2, 0, 1, 2);
|
||||
gridLayout->addWidget(dialogButtons, 3, 0, 1, 2);
|
||||
}
|
||||
|
||||
OptionsDialog::~OptionsDialog()
|
||||
{
|
||||
m_optionsFuture.cancel();
|
||||
m_optionsFuture.waitForFinished();
|
||||
}
|
||||
|
||||
QStringList OptionsDialog::sdkManagerArguments() const
|
||||
{
|
||||
QString userInput = argumentsEdit->text().simplified();
|
||||
return userInput.isEmpty() ? QStringList() : userInput.split(' ');
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Android
|
||||
|
@@ -52,7 +52,7 @@ class AndroidSdkManagerWidget : public QWidget
|
||||
};
|
||||
|
||||
public:
|
||||
AndroidSdkManagerWidget(const AndroidConfig &config, AndroidSdkManager *sdkManager,
|
||||
AndroidSdkManagerWidget(AndroidConfig &config, AndroidSdkManager *sdkManager,
|
||||
QWidget *parent = nullptr);
|
||||
~AndroidSdkManagerWidget();
|
||||
|
||||
@@ -68,6 +68,7 @@ private:
|
||||
void onCancel();
|
||||
void onNativeSdkManager();
|
||||
void onOperationResult(int index);
|
||||
void onSdkManagerOptions();
|
||||
void addPackageFuture(const QFuture<AndroidSdkManager::OperationOutput> &future);
|
||||
void notifyOperationFinished();
|
||||
void packageFutureFinished();
|
||||
@@ -75,7 +76,7 @@ private:
|
||||
void switchView(View view);
|
||||
View currentView() const;
|
||||
|
||||
const AndroidConfig &m_androidConfig;
|
||||
AndroidConfig &m_androidConfig;
|
||||
AndroidSdkManager *m_sdkManager = nullptr;
|
||||
AndroidSdkModel *m_sdkModel = nullptr;
|
||||
Ui::AndroidSdkManagerWidget *m_ui = nullptr;
|
||||
|
@@ -175,6 +175,13 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="optionsButton">
|
||||
<property name="text">
|
||||
<string>Advanced Options...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
|
Reference in New Issue
Block a user