diff --git a/src/plugins/help/images/home.png b/src/libs/utils/images/home.png
similarity index 100%
rename from src/plugins/help/images/home.png
rename to src/libs/utils/images/home.png
diff --git a/src/plugins/help/images/home@2x.png b/src/libs/utils/images/home@2x.png
similarity index 100%
rename from src/plugins/help/images/home@2x.png
rename to src/libs/utils/images/home@2x.png
diff --git a/src/libs/utils/images/project.png b/src/libs/utils/images/project.png
new file mode 100644
index 00000000000..f43b78dee09
Binary files /dev/null and b/src/libs/utils/images/project.png differ
diff --git a/src/libs/utils/images/project@2x.png b/src/libs/utils/images/project@2x.png
new file mode 100644
index 00000000000..432016e10f9
Binary files /dev/null and b/src/libs/utils/images/project@2x.png differ
diff --git a/src/libs/utils/json.cpp b/src/libs/utils/json.cpp
index d0cc0bbd136..ae97e1fd528 100644
--- a/src/libs/utils/json.cpp
+++ b/src/libs/utils/json.cpp
@@ -671,7 +671,7 @@ JsonSchemaManager::JsonSchemaManager(const QStringList &searchPaths)
{
foreach (const QString &path, m_searchPaths) {
QDir dir(path);
- if (!dir.exists() && !dir.mkpath(path))
+ if (!dir.exists())
continue;
dir.setNameFilters(QStringList(QLatin1String("*.json")));
foreach (const QFileInfo &fi, dir.entryInfoList())
diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc
index 63ca09e10f5..95a473da2ab 100644
--- a/src/libs/utils/utils.qrc
+++ b/src/libs/utils/utils.qrc
@@ -176,5 +176,9 @@
images/pan@2x.png
images/wizardicon-file.png
images/wizardicon-file@2x.png
+ images/project.png
+ images/project@2x.png
+ images/home.png
+ images/home@2x.png
diff --git a/src/libs/utils/utilsicons.cpp b/src/libs/utils/utilsicons.cpp
index 271d3122f66..016d3d5fb46 100644
--- a/src/libs/utils/utilsicons.cpp
+++ b/src/libs/utils/utilsicons.cpp
@@ -28,6 +28,11 @@
namespace Utils {
namespace Icons {
+
+const Icon HOME({
+ {QLatin1String(":/utils/images/home.png"), Utils::Theme::PanelTextColorDark}}, Icon::Tint);
+const Icon HOME_TOOLBAR({
+ {QLatin1String(":/utils/images/home.png"), Utils::Theme::IconsBaseColor}});
const Icon EDIT_CLEAR({
{QLatin1String(":/utils/images/editclear.png"), Theme::PanelTextColorMid}}, Icon::Tint);
const Icon EDIT_CLEAR_TOOLBAR({
@@ -46,6 +51,8 @@ const Icon PREV({
{QLatin1String(":/utils/images/prev.png"), Theme::IconsWarningColor}}, Icon::MenuTintedStyle);
const Icon PREV_TOOLBAR({
{QLatin1String(":/utils/images/prev.png"), Theme::IconsNavigationArrowsColor}});
+const Icon PROJECT({
+ {QLatin1String(":/utils/images/project.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon ZOOM({
{QLatin1String(":/utils/images/zoom.png"), Theme::PanelTextColorMid}}, Icon::Tint);
const Icon ZOOM_TOOLBAR({
diff --git a/src/libs/utils/utilsicons.h b/src/libs/utils/utilsicons.h
index 5725e9a5382..9a3a586e147 100644
--- a/src/libs/utils/utilsicons.h
+++ b/src/libs/utils/utilsicons.h
@@ -31,6 +31,8 @@
namespace Utils {
namespace Icons {
+QTCREATOR_UTILS_EXPORT extern const Icon HOME;
+QTCREATOR_UTILS_EXPORT extern const Icon HOME_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon EDIT_CLEAR;
QTCREATOR_UTILS_EXPORT extern const Icon EDIT_CLEAR_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon LOCKED_TOOLBAR;
@@ -40,6 +42,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon NEXT;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon PREV;
QTCREATOR_UTILS_EXPORT extern const Icon PREV_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon PROJECT;
QTCREATOR_UTILS_EXPORT extern const Icon ZOOM;
QTCREATOR_UTILS_EXPORT extern const Icon ZOOM_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon ZOOMIN_TOOLBAR;
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro
index 67cc03f6ca4..3c2a5669b5c 100644
--- a/src/plugins/android/android.pro
+++ b/src/plugins/android/android.pro
@@ -50,7 +50,10 @@ HEADERS += \
androidsdkmanager.h \
androidavdmanager.h \
androidrunconfigurationwidget.h \
- adbcommandswidget.h
+ adbcommandswidget.h \
+ androidsdkpackage.h \
+ androidsdkmodel.h \
+ androidsdkmanagerwidget.h
SOURCES += \
androidconfigurations.cpp \
@@ -94,7 +97,10 @@ SOURCES += \
androidsdkmanager.cpp \
androidavdmanager.cpp \
androidrunconfigurationwidget.cpp \
- adbcommandswidget.cpp
+ adbcommandswidget.cpp \
+ androidsdkpackage.cpp \
+ androidsdkmodel.cpp \
+ androidsdkmanagerwidget.cpp
FORMS += \
androidsettingswidget.ui \
@@ -104,7 +110,8 @@ FORMS += \
androiddeployqtwidget.ui \
androidbuildapkwidget.ui \
androidrunconfigurationwidget.ui \
- adbcommandswidget.ui
+ adbcommandswidget.ui \
+ androidsdkmanagerwidget.ui
RESOURCES = android.qrc
diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp
index 028fe2c7974..5af95e7a260 100644
--- a/src/plugins/android/androidavdmanager.cpp
+++ b/src/plugins/android/androidavdmanager.cpp
@@ -54,8 +54,6 @@ const char avdInfoAbiKey[] = "abi.type";
const char avdInfoTargetKey[] = "target";
const char avdInfoErrorKey[] = "Error:";
-const QVersionNumber avdManagerIntroVersion(25, 3 ,0);
-
const int avdCreateTimeoutMs = 30000;
/*!
@@ -101,37 +99,37 @@ static bool checkForTimeout(const chrono::steady_clock::time_point &start,
return timedOut;
}
-static AndroidConfig::CreateAvdInfo createAvdCommand(const AndroidConfig config,
- const AndroidConfig::CreateAvdInfo &info)
+static CreateAvdInfo createAvdCommand(const AndroidConfig config, const CreateAvdInfo &info)
{
- AndroidConfig::CreateAvdInfo result = info;
+ CreateAvdInfo result = info;
if (!result.isValid()) {
qCDebug(avdManagerLog) << "AVD Create failed. Invalid CreateAvdInfo" << result.name
- << result.target.name << result.target.apiLevel;
+ << result.sdkPlatform->displayText() << result.sdkPlatform->apiLevel();
result.error = QApplication::translate("AndroidAvdManager",
"Cannot create AVD. Invalid input.");
return result;
}
- QStringList arguments({"create", "avd", "-k", result.target.package, "-n", result.name});
+ QStringList arguments({"create", "avd", "-k", result.sdkPlatform->sdkStylePath(), "-n", result.name});
if (!result.abi.isEmpty()) {
- SystemImage image = Utils::findOrDefault(result.target.systemImages,
+ SystemImage *image = Utils::findOrDefault(result.sdkPlatform->systemImages(),
Utils::equal(&SystemImage::abiName, result.abi));
- if (image.isValid()) {
- arguments << "-k" << image.package;
+ if (image && image->isValid()) {
+ arguments << "-k" << image->sdkStylePath();
} else {
+ QString name = result.sdkPlatform->displayText();
qCDebug(avdManagerLog) << "AVD Create failed. Cannot find system image for the platform"
- << result.abi << result.target.name;
+ << result.abi << name;
result.error = QApplication::translate("AndroidAvdManager",
"Cannot create AVD. Cannot find system image for "
- "the ABI %1(%2).").arg(result.abi).arg(result.target.name);
+ "the ABI %1(%2).").arg(result.abi).arg(name);
return result;
}
} else {
- arguments << "-k" << result.target.package;
+ arguments << "-k" << result.sdkPlatform->sdkStylePath();
}
if (result.sdcardSize > 0)
@@ -219,14 +217,9 @@ AndroidAvdManager::~AndroidAvdManager()
}
-bool AndroidAvdManager::avdManagerUiToolAvailable() const
-{
- return m_config.sdkToolsVersion() < avdManagerIntroVersion;
-}
-
void AndroidAvdManager::launchAvdManagerUiTool() const
{
- if (avdManagerUiToolAvailable()) {
+ if (m_config.useNativeUiTools()) {
m_androidTool->launchAvdManager();
} else {
qCDebug(avdManagerLog) << "AVD Ui tool launch failed. UI tool not available"
@@ -234,10 +227,9 @@ void AndroidAvdManager::launchAvdManagerUiTool() const
}
}
-QFuture
-AndroidAvdManager::createAvd(AndroidConfig::CreateAvdInfo info) const
+QFuture AndroidAvdManager::createAvd(CreateAvdInfo info) const
{
- if (m_config.sdkToolsVersion() < avdManagerIntroVersion)
+ if (m_config.useNativeUiTools())
return m_androidTool->createAvd(info);
return Utils::runAsync(&createAvdCommand, m_config, info);
@@ -245,7 +237,7 @@ AndroidAvdManager::createAvd(AndroidConfig::CreateAvdInfo info) const
bool AndroidAvdManager::removeAvd(const QString &name) const
{
- if (m_config.sdkToolsVersion() < avdManagerIntroVersion)
+ if (m_config.useNativeUiTools())
return m_androidTool->removeAvd(name);
Utils::SynchronousProcess proc;
@@ -258,7 +250,7 @@ bool AndroidAvdManager::removeAvd(const QString &name) const
QFuture AndroidAvdManager::avdList() const
{
- if (m_config.sdkToolsVersion() < avdManagerIntroVersion)
+ if (m_config.useNativeUiTools())
return m_androidTool->androidVirtualDevicesFuture();
return Utils::runAsync(&AvdManagerOutputParser::listVirtualDevices, m_parser.get(), m_config);
diff --git a/src/plugins/android/androidavdmanager.h b/src/plugins/android/androidavdmanager.h
index 4e8633efda9..8bb487ca663 100644
--- a/src/plugins/android/androidavdmanager.h
+++ b/src/plugins/android/androidavdmanager.h
@@ -40,9 +40,8 @@ public:
AndroidAvdManager(const AndroidConfig& config = AndroidConfigurations::currentConfig());
~AndroidAvdManager();
- bool avdManagerUiToolAvailable() const;
void launchAvdManagerUiTool() const;
- QFuture createAvd(AndroidConfig::CreateAvdInfo info) const;
+ QFuture createAvd(CreateAvdInfo info) const;
bool removeAvd(const QString &name) const;
QFuture avdList() const;
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp
index e3a648c8b44..e3dab7ad7bd 100644
--- a/src/plugins/android/androidbuildapkstep.cpp
+++ b/src/plugins/android/androidbuildapkstep.cpp
@@ -29,6 +29,7 @@
#include "androidconfigurations.h"
#include "androidconstants.h"
#include "androidmanager.h"
+#include "androidsdkmanager.h"
#include "androidqtsupport.h"
#include "certificatesmodel.h"
@@ -92,7 +93,8 @@ private:
AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent, const Core::Id id)
: ProjectExplorer::AbstractProcessStep(parent, id),
- m_buildTargetSdk(AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk()))
+ m_buildTargetSdk(AndroidConfig::apiLevelNameFor(AndroidConfigurations::
+ sdkManager()->latestAndroidSdkPlatform()))
{
//: AndroidBuildApkStep default display name
setDefaultDisplayName(tr("Build Android APK"));
@@ -233,8 +235,10 @@ bool AndroidBuildApkStep::fromMap(const QVariantMap &map)
m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
m_signPackage = false; // don't restore this
m_buildTargetSdk = map.value(BuildTargetSdkKey).toString();
- if (m_buildTargetSdk.isEmpty())
- m_buildTargetSdk = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
+ if (m_buildTargetSdk.isEmpty()) {
+ m_buildTargetSdk = AndroidConfig::apiLevelNameFor(AndroidConfigurations::
+ sdkManager()->latestAndroidSdkPlatform());
+ }
m_verbose = map.value(VerboseOutputKey).toBool();
m_useMinistro = map.value(UseMinistroKey).toBool();
return ProjectExplorer::BuildStep::fromMap(map);
diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp
index 18b1fff3279..dceb496f5ec 100644
--- a/src/plugins/android/androidbuildapkwidget.cpp
+++ b/src/plugins/android/androidbuildapkwidget.cpp
@@ -29,6 +29,7 @@
#include "androidconfigurations.h"
#include "androidcreatekeystorecertificate.h"
#include "androidmanager.h"
+#include "androidsdkmanager.h"
#include "ui_androidbuildapkwidget.h"
#include
@@ -47,6 +48,8 @@
using namespace Android;
using namespace Internal;
+const int minApiSupported = 9;
+
AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
: ProjectExplorer::BuildStepConfigWidget(),
m_ui(new Ui::AndroidBuildApkWidget),
@@ -55,9 +58,8 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
m_ui->setupUi(this);
// Target sdk combobox
- int minApiLevel = 9;
- const AndroidConfig &config = AndroidConfigurations::currentConfig();
- QStringList targets = AndroidConfig::apiLevelNamesFor(config.sdkTargets(minApiLevel));
+ QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::sdkManager()->
+ filteredSdkPlatforms(minApiSupported));
targets.removeDuplicates();
m_ui->targetSDKComboBox->addItems(targets);
m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::buildTargetSDK(step->target())));
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index b52810e93f0..a44f605780e 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -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());
@@ -272,7 +275,6 @@ void AndroidConfig::load(const QSettings &settings)
m_makeExtraSearchDirectories << extraDirectory;
// persistent settings
}
- m_availableSdkPlatformsUpToDate = false;
m_NdkInformationUpToDate = false;
}
@@ -284,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());
@@ -333,40 +336,15 @@ void AndroidConfig::updateNdkInformation() const
m_NdkInformationUpToDate = true;
}
-void AndroidConfig::updateAvailableSdkPlatforms() const
-{
- if (m_availableSdkPlatformsUpToDate)
- return;
-
- m_availableSdkPlatforms.clear();
- AndroidSdkManager sdkManager(*this);
- bool success = false;
- m_availableSdkPlatforms = sdkManager.availableSdkPlatforms(&success);
- if (success)
- m_availableSdkPlatformsUpToDate = true;
-}
-
-QStringList AndroidConfig::apiLevelNamesFor(const QList &platforms)
+QStringList AndroidConfig::apiLevelNamesFor(const SdkPlatformList &platforms)
{
return Utils::transform(platforms, AndroidConfig::apiLevelNameFor);
}
-QString AndroidConfig::apiLevelNameFor(const SdkPlatform &platform)
+QString AndroidConfig::apiLevelNameFor(const SdkPlatform *platform)
{
- return platform.apiLevel > 0 ? QString("android-%1").arg(platform.apiLevel) : "";
-}
-
-QList AndroidConfig::sdkTargets(int minApiLevel) const
-{
- updateAvailableSdkPlatforms();
- QList result;
- for (int i = 0; i < m_availableSdkPlatforms.size(); ++i) {
- if (m_availableSdkPlatforms.at(i).apiLevel >= minApiLevel)
- result << m_availableSdkPlatforms.at(i);
- else
- break;
- }
- return result;
+ return platform && platform->apiLevel() > 0 ?
+ QString("android-%1").arg(platform->apiLevel()) : "";
}
FileName AndroidConfig::adbToolPath() const
@@ -523,20 +501,6 @@ QVector AndroidConfig::connectedDevices(const QString &adbToo
return devices;
}
-AndroidConfig::CreateAvdInfo AndroidConfig::gatherCreateAVDInfo(QWidget *parent, int minApiLevel, QString targetArch) const
-{
- CreateAvdInfo result;
- AvdDialog d(minApiLevel, targetArch, this, parent);
- if (d.exec() != QDialog::Accepted || !d.isValid())
- return result;
-
- result.target = d.target();
- result.name = d.name();
- result.abi = d.abi();
- result.sdcardSize = d.sdcardSize();
- return result;
-}
-
bool AndroidConfig::isConnected(const QString &serialNumber) const
{
QVector devices = connectedDevices();
@@ -716,12 +680,10 @@ QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &de
return result;
}
-SdkPlatform AndroidConfig::highestAndroidSdk() const
+bool AndroidConfig::useNativeUiTools() const
{
- updateAvailableSdkPlatforms();
- if (m_availableSdkPlatforms.isEmpty())
- return SdkPlatform();
- return m_availableSdkPlatforms.first();
+ const QVersionNumber version = sdkToolsVersion();
+ return !version.isNull() && version <= QVersionNumber(25, 3 ,0);
}
QString AndroidConfig::bestNdkPlatformMatch(int target) const
@@ -743,7 +705,6 @@ FileName AndroidConfig::sdkLocation() const
void AndroidConfig::setSdkLocation(const FileName &sdkLocation)
{
m_sdkLocation = sdkLocation;
- m_availableSdkPlatformsUpToDate = false;
}
QVersionNumber AndroidConfig::sdkToolsVersion() const
@@ -770,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;
@@ -836,7 +808,6 @@ FileName AndroidConfig::openJDKLocation() const
void AndroidConfig::setOpenJDKLocation(const FileName &openJDKLocation)
{
m_openJDKLocation = openJDKLocation;
- m_availableSdkPlatformsUpToDate = false;
}
FileName AndroidConfig::keystoreLocation() const
@@ -1129,6 +1100,11 @@ const AndroidConfig &AndroidConfigurations::currentConfig()
return m_instance->m_config; // ensure that m_instance is initialized
}
+AndroidSdkManager *AndroidConfigurations::sdkManager()
+{
+ return m_instance->m_sdkManager.get();
+}
+
AndroidConfigurations *AndroidConfigurations::instance()
{
return m_instance;
@@ -1143,7 +1119,8 @@ void AndroidConfigurations::save()
}
AndroidConfigurations::AndroidConfigurations(QObject *parent)
- : QObject(parent)
+ : QObject(parent),
+ m_sdkManager(new AndroidSdkManager(m_config))
{
load();
@@ -1155,6 +1132,11 @@ AndroidConfigurations::AndroidConfigurations(QObject *parent)
m_instance = this;
}
+AndroidConfigurations::~AndroidConfigurations()
+{
+
+}
+
static FileName javaHomeForJavac(const FileName &location)
{
QFileInfo fileInfo = location.toFileInfo();
@@ -1265,13 +1247,4 @@ void AndroidConfigurations::updateAndroidDevice()
AndroidConfigurations *AndroidConfigurations::m_instance = 0;
-bool SdkPlatform::operator <(const SdkPlatform &other) const
-{
- if (apiLevel != other.apiLevel)
- return apiLevel > other.apiLevel;
- if (name != other.name)
- return name < other.name;
- return false;
-}
-
} // namespace Android
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index 75b6dd16abc..4565d5e3635 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -26,7 +26,7 @@
#pragma once
#include "android_global.h"
-
+#include "androidsdkpackage.h"
#include
#include
@@ -52,7 +52,9 @@ class Project;
namespace Utils { class Environment; }
namespace Android {
+
class AndroidPlugin;
+namespace Internal { class AndroidSdkManager; }
class AndroidDeviceInfo
{
@@ -74,31 +76,16 @@ public:
};
using AndroidDeviceInfoList = QList;
-//! Defines an Android system image.
-class SystemImage
+class CreateAvdInfo
{
public:
- bool isValid() const { return (apiLevel != -1) && !abiName.isEmpty(); }
- int apiLevel = -1;
- QString abiName;
- QString package;
- Utils::FileName installedLocation;
-};
-using SystemImageList = QList;
-
-
-class SdkPlatform
-{
-public:
- bool isValid() const { return !name.isEmpty() && apiLevel != -1; }
- bool operator <(const SdkPlatform &other) const;
- int apiLevel = -1;
+ bool isValid() const { return sdkPlatform && sdkPlatform->isValid() && !name.isEmpty(); }
+ const SdkPlatform *sdkPlatform = nullptr;
QString name;
- QString package;
- Utils::FileName installedLocation;
- SystemImageList systemImages;
+ QString abi;
+ int sdcardSize = 0;
+ QString error; // only used in the return value of createAVD
};
-using SdkPlatformList = QList;
class ANDROID_EXPORT AndroidConfig
{
@@ -106,14 +93,15 @@ public:
void load(const QSettings &settings);
void save(QSettings &settings) const;
- static QStringList apiLevelNamesFor(const QList &platforms);
- static QString apiLevelNameFor(const SdkPlatform &platform);
- QList sdkTargets(int minApiLevel = 0) const;
+ static QStringList apiLevelNamesFor(const SdkPlatformList &platforms);
+ static QString apiLevelNameFor(const SdkPlatform *platform);
Utils::FileName sdkLocation() const;
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;
@@ -147,19 +135,6 @@ public:
Utils::FileName keytoolPath() const;
- class CreateAvdInfo
- {
- public:
- bool isValid() const { return target.isValid() && !name.isEmpty(); }
- SdkPlatform target;
- QString name;
- QString abi;
- int sdcardSize = 0;
- QString error; // only used in the return value of createAVD
- };
-
- CreateAvdInfo gatherCreateAVDInfo(QWidget *parent, int minApiLevel = 0, QString targetArch = QString()) const;
-
QVector connectedDevices(QString *error = 0) const;
static QVector connectedDevices(const QString &adbToolPath, QString *error = 0);
@@ -175,7 +150,8 @@ public:
OpenGl getOpenGLEnabled(const QString &emulator) const;
bool isConnected(const QString &serialNumber) const;
- SdkPlatform highestAndroidSdk() const;
+ bool useNativeUiTools() const;
+
private:
static QString getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property);
@@ -189,10 +165,10 @@ private:
bool isBootToQt(const QString &device) const;
static QString getAvdName(const QString &serialnumber);
- void updateAvailableSdkPlatforms() const;
void updateNdkInformation() const;
Utils::FileName m_sdkLocation;
+ QStringList m_sdkManagerToolArgs;
Utils::FileName m_ndkLocation;
Utils::FileName m_openJDKLocation;
Utils::FileName m_keystoreLocation;
@@ -201,9 +177,6 @@ private:
bool m_automaticKitCreation = true;
//caches
- mutable bool m_availableSdkPlatformsUpToDate = false;
- mutable SdkPlatformList m_availableSdkPlatforms;
-
mutable bool m_NdkInformationUpToDate = false;
mutable QString m_toolchainHost;
mutable QVector m_availableNdkPlatforms;
@@ -218,6 +191,7 @@ class ANDROID_EXPORT AndroidConfigurations : public QObject
public:
static const AndroidConfig ¤tConfig();
+ static Internal::AndroidSdkManager *sdkManager();
static void setConfig(const AndroidConfig &config);
static AndroidConfigurations *instance();
@@ -236,16 +210,17 @@ signals:
private:
AndroidConfigurations(QObject *parent);
+ ~AndroidConfigurations();
void load();
void save();
static AndroidConfigurations *m_instance;
AndroidConfig m_config;
+ std::unique_ptr m_sdkManager;
QMap > m_defaultDeviceForAbi;
bool m_force32bit;
};
} // namespace Android
-Q_DECLARE_METATYPE(Android::SdkPlatform)
diff --git a/src/plugins/android/androiddevicedialog.cpp b/src/plugins/android/androiddevicedialog.cpp
index 67cd02e9f84..9c07238d2dc 100644
--- a/src/plugins/android/androiddevicedialog.cpp
+++ b/src/plugins/android/androiddevicedialog.cpp
@@ -26,6 +26,7 @@
#include "androiddevicedialog.h"
#include "androidmanager.h"
#include "androidavdmanager.h"
+#include "avddialog.h"
#include "ui_androiddevicedialog.h"
#include
@@ -580,9 +581,10 @@ void AndroidDeviceDialog::devicesRefreshed()
void AndroidDeviceDialog::createAvd()
{
m_ui->createAVDButton->setEnabled(false);
- AndroidConfig::CreateAvdInfo info = AndroidConfigurations::currentConfig().gatherCreateAVDInfo(this, m_apiLevel, m_abi);
+ CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, AndroidConfigurations::sdkManager(),
+ m_apiLevel, m_abi);
- if (!info.target.isValid()) {
+ if (!info.isValid()) {
m_ui->createAVDButton->setEnabled(true);
return;
}
@@ -593,7 +595,7 @@ void AndroidDeviceDialog::createAvd()
void AndroidDeviceDialog::avdAdded()
{
m_ui->createAVDButton->setEnabled(true);
- AndroidConfig::CreateAvdInfo info = m_futureWatcherAddDevice.result();
+ CreateAvdInfo info = m_futureWatcherAddDevice.result();
if (!info.error.isEmpty()) {
QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
return;
diff --git a/src/plugins/android/androiddevicedialog.h b/src/plugins/android/androiddevicedialog.h
index f882b0bfcd2..db379c068e9 100644
--- a/src/plugins/android/androiddevicedialog.h
+++ b/src/plugins/android/androiddevicedialog.h
@@ -79,7 +79,7 @@ private:
QString m_defaultDevice;
std::unique_ptr m_avdManager;
QVector m_connectedDevices;
- QFutureWatcher m_futureWatcherAddDevice;
+ QFutureWatcher m_futureWatcherAddDevice;
QFutureWatcher m_futureWatcherRefreshDevices;
};
diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp
index bec6c84ddb9..460c749ebad 100644
--- a/src/plugins/android/androidmanager.cpp
+++ b/src/plugins/android/androidmanager.cpp
@@ -35,6 +35,7 @@
#include "androidqtversion.h"
#include "androidbuildapkstep.h"
#include "androidavdmanager.h"
+#include "androidsdkmanager.h"
#include
#include
@@ -174,7 +175,8 @@ QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target)
if (androidBuildApkStep)
return androidBuildApkStep->buildTargetSdk();
- QString fallback = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
+ QString fallback = AndroidConfig::apiLevelNameFor(
+ AndroidConfigurations::sdkManager()->latestAndroidSdkPlatform());
return fallback;
}
diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp
index ac518bdd21c..4adf95401ea 100644
--- a/src/plugins/android/androidsdkmanager.cpp
+++ b/src/plugins/android/androidsdkmanager.cpp
@@ -24,15 +24,19 @@
****************************************************************************/
#include "androidsdkmanager.h"
+#include "androidconstants.h"
#include "androidmanager.h"
#include "androidtoolmanager.h"
#include "utils/algorithm.h"
#include "utils/qtcassert.h"
+#include "utils/runextensions.h"
#include "utils/synchronousprocess.h"
-#include "utils/environment.h"
+#include "utils/qtcprocess.h"
+#include
#include
+#include
#include
#include
@@ -48,12 +52,32 @@ namespace Internal {
const QVersionNumber sdkManagerIntroVersion(25, 3 ,0);
const char installLocationKey[] = "Installed Location:";
-const char apiLevelPropertyKey[] = "AndroidVersion.ApiLevel";
-const char abiPropertyKey[] = "SystemImage.Abi";
+const char revisionKey[] = "Version:";
+const char descriptionKey[] = "Description:";
+const char commonArgsKey[] = "Common Arguments:";
const int sdkManagerCmdTimeoutS = 60;
+const int sdkManagerOperationTimeoutS = 600;
+
+const QRegularExpression assertionReg("(\\(\\s*y\\s*[\\/\\\\]\\s*n\\s*\\)\\s*)(?[\\:\\?])",
+ QRegularExpression::CaseInsensitiveOption |
+ QRegularExpression::MultilineOption);
using namespace Utils;
+using SdkCmdFutureInterface = QFutureInterface;
+
+int platformNameToApiLevel(const QString &platformName)
+{
+ int apiLevel = -1;
+ QRegularExpression re("(android-)(?[0-9]{1,})",
+ QRegularExpression::CaseInsensitiveOption);
+ QRegularExpressionMatch match = re.match(platformName);
+ if (match.hasMatch()) {
+ QString apiLevelStr = match.captured("apiLevel");
+ apiLevel = apiLevelStr.toInt();
+ }
+ return apiLevel;
+}
/*!
Parses the \a line for a [spaces]key[spaces]value[spaces] pattern and returns
@@ -70,24 +94,139 @@ static bool valueForKey(QString key, const QString &line, QString *value = nullp
return false;
}
-/*!
- Runs the \c sdkmanger tool specific to configuration \a config with arguments \a args. Returns
- \c true if the command is successfully executed. Output is copied into \a output. The function
- blocks the calling thread.
- */
-static bool sdkManagerCommand(const AndroidConfig config, const QStringList &args, QString *output,
- int timeout = sdkManagerCmdTimeoutS)
+int parseProgress(const QString &out, bool &foundAssertion)
+{
+ int progress = -1;
+ if (out.isEmpty())
+ return progress;
+ QRegularExpression reg("(?