forked from qt-creator/qt-creator
Android: Refactor Android SDK packages
Introduce a hierarchy for Android SDK packages and refactor the code accordingly. This is ground work for sdk management and automatic android setup Task-number: QTCREATORBUG-18978 Change-Id: Idef545e3b3a8e33e920be52b26094fb8046afcd3 Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
@@ -50,7 +50,8 @@ HEADERS += \
|
|||||||
androidsdkmanager.h \
|
androidsdkmanager.h \
|
||||||
androidavdmanager.h \
|
androidavdmanager.h \
|
||||||
androidrunconfigurationwidget.h \
|
androidrunconfigurationwidget.h \
|
||||||
adbcommandswidget.h
|
adbcommandswidget.h \
|
||||||
|
androidsdkpackage.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
androidconfigurations.cpp \
|
androidconfigurations.cpp \
|
||||||
@@ -94,7 +95,8 @@ SOURCES += \
|
|||||||
androidsdkmanager.cpp \
|
androidsdkmanager.cpp \
|
||||||
androidavdmanager.cpp \
|
androidavdmanager.cpp \
|
||||||
androidrunconfigurationwidget.cpp \
|
androidrunconfigurationwidget.cpp \
|
||||||
adbcommandswidget.cpp
|
adbcommandswidget.cpp \
|
||||||
|
androidsdkpackage.cpp
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
androidsettingswidget.ui \
|
androidsettingswidget.ui \
|
||||||
|
|||||||
@@ -101,37 +101,37 @@ static bool checkForTimeout(const chrono::steady_clock::time_point &start,
|
|||||||
return timedOut;
|
return timedOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AndroidConfig::CreateAvdInfo createAvdCommand(const AndroidConfig config,
|
static CreateAvdInfo createAvdCommand(const AndroidConfig config, const CreateAvdInfo &info)
|
||||||
const AndroidConfig::CreateAvdInfo &info)
|
|
||||||
{
|
{
|
||||||
AndroidConfig::CreateAvdInfo result = info;
|
CreateAvdInfo result = info;
|
||||||
|
|
||||||
if (!result.isValid()) {
|
if (!result.isValid()) {
|
||||||
qCDebug(avdManagerLog) << "AVD Create failed. Invalid CreateAvdInfo" << result.name
|
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",
|
result.error = QApplication::translate("AndroidAvdManager",
|
||||||
"Cannot create AVD. Invalid input.");
|
"Cannot create AVD. Invalid input.");
|
||||||
return result;
|
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()) {
|
if (!result.abi.isEmpty()) {
|
||||||
SystemImage image = Utils::findOrDefault(result.target.systemImages,
|
SystemImage *image = Utils::findOrDefault(result.sdkPlatform->systemImages(),
|
||||||
Utils::equal(&SystemImage::abiName, result.abi));
|
Utils::equal(&SystemImage::abiName, result.abi));
|
||||||
if (image.isValid()) {
|
if (image && image->isValid()) {
|
||||||
arguments << "-k" << image.package;
|
arguments << "-k" << image->sdkStylePath();
|
||||||
} else {
|
} else {
|
||||||
|
QString name = result.sdkPlatform->displayText();
|
||||||
qCDebug(avdManagerLog) << "AVD Create failed. Cannot find system image for the platform"
|
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",
|
result.error = QApplication::translate("AndroidAvdManager",
|
||||||
"Cannot create AVD. Cannot find system image for "
|
"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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
arguments << "-k" << result.target.package;
|
arguments << "-k" << result.sdkPlatform->sdkStylePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.sdcardSize > 0)
|
if (result.sdcardSize > 0)
|
||||||
@@ -234,8 +234,7 @@ void AndroidAvdManager::launchAvdManagerUiTool() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<AndroidConfig::CreateAvdInfo>
|
QFuture<CreateAvdInfo> AndroidAvdManager::createAvd(CreateAvdInfo info) const
|
||||||
AndroidAvdManager::createAvd(AndroidConfig::CreateAvdInfo info) const
|
|
||||||
{
|
{
|
||||||
if (m_config.sdkToolsVersion() < avdManagerIntroVersion)
|
if (m_config.sdkToolsVersion() < avdManagerIntroVersion)
|
||||||
return m_androidTool->createAvd(info);
|
return m_androidTool->createAvd(info);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
|
|
||||||
bool avdManagerUiToolAvailable() const;
|
bool avdManagerUiToolAvailable() const;
|
||||||
void launchAvdManagerUiTool() const;
|
void launchAvdManagerUiTool() const;
|
||||||
QFuture<AndroidConfig::CreateAvdInfo> createAvd(AndroidConfig::CreateAvdInfo info) const;
|
QFuture<CreateAvdInfo> createAvd(CreateAvdInfo info) const;
|
||||||
bool removeAvd(const QString &name) const;
|
bool removeAvd(const QString &name) const;
|
||||||
QFuture<AndroidDeviceInfoList> avdList() const;
|
QFuture<AndroidDeviceInfoList> avdList() const;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "androidconfigurations.h"
|
#include "androidconfigurations.h"
|
||||||
#include "androidconstants.h"
|
#include "androidconstants.h"
|
||||||
#include "androidmanager.h"
|
#include "androidmanager.h"
|
||||||
|
#include "androidsdkmanager.h"
|
||||||
#include "androidqtsupport.h"
|
#include "androidqtsupport.h"
|
||||||
#include "certificatesmodel.h"
|
#include "certificatesmodel.h"
|
||||||
|
|
||||||
@@ -92,7 +93,8 @@ private:
|
|||||||
|
|
||||||
AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent, const Core::Id id)
|
AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent, const Core::Id id)
|
||||||
: ProjectExplorer::AbstractProcessStep(parent, id),
|
: ProjectExplorer::AbstractProcessStep(parent, id),
|
||||||
m_buildTargetSdk(AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk()))
|
m_buildTargetSdk(AndroidConfig::apiLevelNameFor(AndroidConfigurations::
|
||||||
|
sdkManager()->latestAndroidSdkPlatform()))
|
||||||
{
|
{
|
||||||
//: AndroidBuildApkStep default display name
|
//: AndroidBuildApkStep default display name
|
||||||
setDefaultDisplayName(tr("Build Android APK"));
|
setDefaultDisplayName(tr("Build Android APK"));
|
||||||
@@ -236,8 +238,10 @@ bool AndroidBuildApkStep::fromMap(const QVariantMap &map)
|
|||||||
m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
|
m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
|
||||||
m_signPackage = false; // don't restore this
|
m_signPackage = false; // don't restore this
|
||||||
m_buildTargetSdk = map.value(BuildTargetSdkKey).toString();
|
m_buildTargetSdk = map.value(BuildTargetSdkKey).toString();
|
||||||
if (m_buildTargetSdk.isEmpty())
|
if (m_buildTargetSdk.isEmpty()) {
|
||||||
m_buildTargetSdk = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
|
m_buildTargetSdk = AndroidConfig::apiLevelNameFor(AndroidConfigurations::
|
||||||
|
sdkManager()->latestAndroidSdkPlatform());
|
||||||
|
}
|
||||||
m_verbose = map.value(VerboseOutputKey).toBool();
|
m_verbose = map.value(VerboseOutputKey).toBool();
|
||||||
return ProjectExplorer::BuildStep::fromMap(map);
|
return ProjectExplorer::BuildStep::fromMap(map);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "androidconfigurations.h"
|
#include "androidconfigurations.h"
|
||||||
#include "androidcreatekeystorecertificate.h"
|
#include "androidcreatekeystorecertificate.h"
|
||||||
#include "androidmanager.h"
|
#include "androidmanager.h"
|
||||||
|
#include "androidsdkmanager.h"
|
||||||
#include "ui_androidbuildapkwidget.h"
|
#include "ui_androidbuildapkwidget.h"
|
||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
@@ -47,6 +48,8 @@
|
|||||||
using namespace Android;
|
using namespace Android;
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
|
const int minApiSupported = 9;
|
||||||
|
|
||||||
AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
|
AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
|
||||||
: ProjectExplorer::BuildStepConfigWidget(),
|
: ProjectExplorer::BuildStepConfigWidget(),
|
||||||
m_ui(new Ui::AndroidBuildApkWidget),
|
m_ui(new Ui::AndroidBuildApkWidget),
|
||||||
@@ -55,9 +58,8 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
|
|||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
// Target sdk combobox
|
// Target sdk combobox
|
||||||
int minApiLevel = 9;
|
QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::sdkManager()->
|
||||||
const AndroidConfig &config = AndroidConfigurations::currentConfig();
|
filteredSdkPlatforms(minApiSupported));
|
||||||
QStringList targets = AndroidConfig::apiLevelNamesFor(config.sdkTargets(minApiLevel));
|
|
||||||
targets.removeDuplicates();
|
targets.removeDuplicates();
|
||||||
m_ui->targetSDKComboBox->addItems(targets);
|
m_ui->targetSDKComboBox->addItems(targets);
|
||||||
m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::buildTargetSDK(step->target())));
|
m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::buildTargetSDK(step->target())));
|
||||||
|
|||||||
@@ -272,7 +272,6 @@ void AndroidConfig::load(const QSettings &settings)
|
|||||||
m_makeExtraSearchDirectories << extraDirectory;
|
m_makeExtraSearchDirectories << extraDirectory;
|
||||||
// persistent settings
|
// persistent settings
|
||||||
}
|
}
|
||||||
m_availableSdkPlatformsUpToDate = false;
|
|
||||||
m_NdkInformationUpToDate = false;
|
m_NdkInformationUpToDate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,40 +332,15 @@ void AndroidConfig::updateNdkInformation() const
|
|||||||
m_NdkInformationUpToDate = true;
|
m_NdkInformationUpToDate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfig::updateAvailableSdkPlatforms() const
|
QStringList AndroidConfig::apiLevelNamesFor(const SdkPlatformList &platforms)
|
||||||
{
|
|
||||||
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<SdkPlatform> &platforms)
|
|
||||||
{
|
{
|
||||||
return Utils::transform(platforms, AndroidConfig::apiLevelNameFor);
|
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) : "";
|
return platform && platform->apiLevel() > 0 ?
|
||||||
}
|
QString("android-%1").arg(platform->apiLevel()) : "";
|
||||||
|
|
||||||
QList<SdkPlatform> AndroidConfig::sdkTargets(int minApiLevel) const
|
|
||||||
{
|
|
||||||
updateAvailableSdkPlatforms();
|
|
||||||
QList<SdkPlatform> 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileName AndroidConfig::adbToolPath() const
|
FileName AndroidConfig::adbToolPath() const
|
||||||
@@ -523,20 +497,6 @@ QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToo
|
|||||||
return devices;
|
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
|
bool AndroidConfig::isConnected(const QString &serialNumber) const
|
||||||
{
|
{
|
||||||
QVector<AndroidDeviceInfo> devices = connectedDevices();
|
QVector<AndroidDeviceInfo> devices = connectedDevices();
|
||||||
@@ -716,14 +676,6 @@ QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &de
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SdkPlatform AndroidConfig::highestAndroidSdk() const
|
|
||||||
{
|
|
||||||
updateAvailableSdkPlatforms();
|
|
||||||
if (m_availableSdkPlatforms.isEmpty())
|
|
||||||
return SdkPlatform();
|
|
||||||
return m_availableSdkPlatforms.first();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AndroidConfig::bestNdkPlatformMatch(int target) const
|
QString AndroidConfig::bestNdkPlatformMatch(int target) const
|
||||||
{
|
{
|
||||||
target = std::max(9, target);
|
target = std::max(9, target);
|
||||||
@@ -743,7 +695,6 @@ FileName AndroidConfig::sdkLocation() const
|
|||||||
void AndroidConfig::setSdkLocation(const FileName &sdkLocation)
|
void AndroidConfig::setSdkLocation(const FileName &sdkLocation)
|
||||||
{
|
{
|
||||||
m_sdkLocation = sdkLocation;
|
m_sdkLocation = sdkLocation;
|
||||||
m_availableSdkPlatformsUpToDate = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVersionNumber AndroidConfig::sdkToolsVersion() const
|
QVersionNumber AndroidConfig::sdkToolsVersion() const
|
||||||
@@ -836,7 +787,6 @@ FileName AndroidConfig::openJDKLocation() const
|
|||||||
void AndroidConfig::setOpenJDKLocation(const FileName &openJDKLocation)
|
void AndroidConfig::setOpenJDKLocation(const FileName &openJDKLocation)
|
||||||
{
|
{
|
||||||
m_openJDKLocation = openJDKLocation;
|
m_openJDKLocation = openJDKLocation;
|
||||||
m_availableSdkPlatformsUpToDate = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileName AndroidConfig::keystoreLocation() const
|
FileName AndroidConfig::keystoreLocation() const
|
||||||
@@ -1129,6 +1079,11 @@ const AndroidConfig &AndroidConfigurations::currentConfig()
|
|||||||
return m_instance->m_config; // ensure that m_instance is initialized
|
return m_instance->m_config; // ensure that m_instance is initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidSdkManager *AndroidConfigurations::sdkManager()
|
||||||
|
{
|
||||||
|
return m_instance->m_sdkManager.get();
|
||||||
|
}
|
||||||
|
|
||||||
AndroidConfigurations *AndroidConfigurations::instance()
|
AndroidConfigurations *AndroidConfigurations::instance()
|
||||||
{
|
{
|
||||||
return m_instance;
|
return m_instance;
|
||||||
@@ -1143,7 +1098,8 @@ void AndroidConfigurations::save()
|
|||||||
}
|
}
|
||||||
|
|
||||||
AndroidConfigurations::AndroidConfigurations(QObject *parent)
|
AndroidConfigurations::AndroidConfigurations(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent),
|
||||||
|
m_sdkManager(new AndroidSdkManager(m_config))
|
||||||
{
|
{
|
||||||
load();
|
load();
|
||||||
|
|
||||||
@@ -1155,6 +1111,11 @@ AndroidConfigurations::AndroidConfigurations(QObject *parent)
|
|||||||
m_instance = this;
|
m_instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidConfigurations::~AndroidConfigurations()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static FileName javaHomeForJavac(const FileName &location)
|
static FileName javaHomeForJavac(const FileName &location)
|
||||||
{
|
{
|
||||||
QFileInfo fileInfo = location.toFileInfo();
|
QFileInfo fileInfo = location.toFileInfo();
|
||||||
@@ -1265,13 +1226,4 @@ void AndroidConfigurations::updateAndroidDevice()
|
|||||||
|
|
||||||
AndroidConfigurations *AndroidConfigurations::m_instance = 0;
|
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
|
} // namespace Android
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "android_global.h"
|
#include "android_global.h"
|
||||||
|
#include "androidsdkpackage.h"
|
||||||
#include <projectexplorer/toolchain.h>
|
#include <projectexplorer/toolchain.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -52,7 +52,9 @@ class Project;
|
|||||||
namespace Utils { class Environment; }
|
namespace Utils { class Environment; }
|
||||||
|
|
||||||
namespace Android {
|
namespace Android {
|
||||||
|
|
||||||
class AndroidPlugin;
|
class AndroidPlugin;
|
||||||
|
namespace Internal { class AndroidSdkManager; }
|
||||||
|
|
||||||
class AndroidDeviceInfo
|
class AndroidDeviceInfo
|
||||||
{
|
{
|
||||||
@@ -74,31 +76,16 @@ public:
|
|||||||
};
|
};
|
||||||
using AndroidDeviceInfoList = QList<AndroidDeviceInfo>;
|
using AndroidDeviceInfoList = QList<AndroidDeviceInfo>;
|
||||||
|
|
||||||
//! Defines an Android system image.
|
class CreateAvdInfo
|
||||||
class SystemImage
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isValid() const { return (apiLevel != -1) && !abiName.isEmpty(); }
|
bool isValid() const { return sdkPlatform && sdkPlatform->isValid() && !name.isEmpty(); }
|
||||||
int apiLevel = -1;
|
const SdkPlatform *sdkPlatform = nullptr;
|
||||||
QString abiName;
|
|
||||||
QString package;
|
|
||||||
Utils::FileName installedLocation;
|
|
||||||
};
|
|
||||||
using SystemImageList = QList<SystemImage>;
|
|
||||||
|
|
||||||
|
|
||||||
class SdkPlatform
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool isValid() const { return !name.isEmpty() && apiLevel != -1; }
|
|
||||||
bool operator <(const SdkPlatform &other) const;
|
|
||||||
int apiLevel = -1;
|
|
||||||
QString name;
|
QString name;
|
||||||
QString package;
|
QString abi;
|
||||||
Utils::FileName installedLocation;
|
int sdcardSize = 0;
|
||||||
SystemImageList systemImages;
|
QString error; // only used in the return value of createAVD
|
||||||
};
|
};
|
||||||
using SdkPlatformList = QList<SdkPlatform>;
|
|
||||||
|
|
||||||
class ANDROID_EXPORT AndroidConfig
|
class ANDROID_EXPORT AndroidConfig
|
||||||
{
|
{
|
||||||
@@ -106,9 +93,8 @@ public:
|
|||||||
void load(const QSettings &settings);
|
void load(const QSettings &settings);
|
||||||
void save(QSettings &settings) const;
|
void save(QSettings &settings) const;
|
||||||
|
|
||||||
static QStringList apiLevelNamesFor(const QList<SdkPlatform> &platforms);
|
static QStringList apiLevelNamesFor(const SdkPlatformList &platforms);
|
||||||
static QString apiLevelNameFor(const SdkPlatform &platform);
|
static QString apiLevelNameFor(const SdkPlatform *platform);
|
||||||
QList<SdkPlatform> sdkTargets(int minApiLevel = 0) const;
|
|
||||||
|
|
||||||
Utils::FileName sdkLocation() const;
|
Utils::FileName sdkLocation() const;
|
||||||
void setSdkLocation(const Utils::FileName &sdkLocation);
|
void setSdkLocation(const Utils::FileName &sdkLocation);
|
||||||
@@ -147,19 +133,6 @@ public:
|
|||||||
|
|
||||||
Utils::FileName keytoolPath() const;
|
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<AndroidDeviceInfo> connectedDevices(QString *error = 0) const;
|
QVector<AndroidDeviceInfo> connectedDevices(QString *error = 0) const;
|
||||||
static QVector<AndroidDeviceInfo> connectedDevices(const QString &adbToolPath, QString *error = 0);
|
static QVector<AndroidDeviceInfo> connectedDevices(const QString &adbToolPath, QString *error = 0);
|
||||||
|
|
||||||
@@ -175,7 +148,6 @@ public:
|
|||||||
OpenGl getOpenGLEnabled(const QString &emulator) const;
|
OpenGl getOpenGLEnabled(const QString &emulator) const;
|
||||||
bool isConnected(const QString &serialNumber) const;
|
bool isConnected(const QString &serialNumber) const;
|
||||||
|
|
||||||
SdkPlatform highestAndroidSdk() const;
|
|
||||||
private:
|
private:
|
||||||
static QString getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property);
|
static QString getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property);
|
||||||
|
|
||||||
@@ -189,7 +161,6 @@ private:
|
|||||||
bool isBootToQt(const QString &device) const;
|
bool isBootToQt(const QString &device) const;
|
||||||
static QString getAvdName(const QString &serialnumber);
|
static QString getAvdName(const QString &serialnumber);
|
||||||
|
|
||||||
void updateAvailableSdkPlatforms() const;
|
|
||||||
void updateNdkInformation() const;
|
void updateNdkInformation() const;
|
||||||
|
|
||||||
Utils::FileName m_sdkLocation;
|
Utils::FileName m_sdkLocation;
|
||||||
@@ -201,9 +172,6 @@ private:
|
|||||||
bool m_automaticKitCreation = true;
|
bool m_automaticKitCreation = true;
|
||||||
|
|
||||||
//caches
|
//caches
|
||||||
mutable bool m_availableSdkPlatformsUpToDate = false;
|
|
||||||
mutable SdkPlatformList m_availableSdkPlatforms;
|
|
||||||
|
|
||||||
mutable bool m_NdkInformationUpToDate = false;
|
mutable bool m_NdkInformationUpToDate = false;
|
||||||
mutable QString m_toolchainHost;
|
mutable QString m_toolchainHost;
|
||||||
mutable QVector<int> m_availableNdkPlatforms;
|
mutable QVector<int> m_availableNdkPlatforms;
|
||||||
@@ -218,6 +186,7 @@ class ANDROID_EXPORT AndroidConfigurations : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static const AndroidConfig ¤tConfig();
|
static const AndroidConfig ¤tConfig();
|
||||||
|
static Internal::AndroidSdkManager *sdkManager();
|
||||||
static void setConfig(const AndroidConfig &config);
|
static void setConfig(const AndroidConfig &config);
|
||||||
static AndroidConfigurations *instance();
|
static AndroidConfigurations *instance();
|
||||||
|
|
||||||
@@ -236,16 +205,17 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
AndroidConfigurations(QObject *parent);
|
AndroidConfigurations(QObject *parent);
|
||||||
|
~AndroidConfigurations();
|
||||||
void load();
|
void load();
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
static AndroidConfigurations *m_instance;
|
static AndroidConfigurations *m_instance;
|
||||||
AndroidConfig m_config;
|
AndroidConfig m_config;
|
||||||
|
std::unique_ptr<Internal::AndroidSdkManager> m_sdkManager;
|
||||||
|
|
||||||
QMap<ProjectExplorer::Project *, QMap<QString, QString> > m_defaultDeviceForAbi;
|
QMap<ProjectExplorer::Project *, QMap<QString, QString> > m_defaultDeviceForAbi;
|
||||||
bool m_force32bit;
|
bool m_force32bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Android
|
} // namespace Android
|
||||||
Q_DECLARE_METATYPE(Android::SdkPlatform)
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "androiddevicedialog.h"
|
#include "androiddevicedialog.h"
|
||||||
#include "androidmanager.h"
|
#include "androidmanager.h"
|
||||||
#include "androidavdmanager.h"
|
#include "androidavdmanager.h"
|
||||||
|
#include "avddialog.h"
|
||||||
#include "ui_androiddevicedialog.h"
|
#include "ui_androiddevicedialog.h"
|
||||||
|
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
@@ -580,9 +581,10 @@ void AndroidDeviceDialog::devicesRefreshed()
|
|||||||
void AndroidDeviceDialog::createAvd()
|
void AndroidDeviceDialog::createAvd()
|
||||||
{
|
{
|
||||||
m_ui->createAVDButton->setEnabled(false);
|
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);
|
m_ui->createAVDButton->setEnabled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -593,7 +595,7 @@ void AndroidDeviceDialog::createAvd()
|
|||||||
void AndroidDeviceDialog::avdAdded()
|
void AndroidDeviceDialog::avdAdded()
|
||||||
{
|
{
|
||||||
m_ui->createAVDButton->setEnabled(true);
|
m_ui->createAVDButton->setEnabled(true);
|
||||||
AndroidConfig::CreateAvdInfo info = m_futureWatcherAddDevice.result();
|
CreateAvdInfo info = m_futureWatcherAddDevice.result();
|
||||||
if (!info.error.isEmpty()) {
|
if (!info.error.isEmpty()) {
|
||||||
QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
|
QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ private:
|
|||||||
QString m_defaultDevice;
|
QString m_defaultDevice;
|
||||||
std::unique_ptr<AndroidAvdManager> m_avdManager;
|
std::unique_ptr<AndroidAvdManager> m_avdManager;
|
||||||
QVector<AndroidDeviceInfo> m_connectedDevices;
|
QVector<AndroidDeviceInfo> m_connectedDevices;
|
||||||
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcherAddDevice;
|
QFutureWatcher<CreateAvdInfo> m_futureWatcherAddDevice;
|
||||||
QFutureWatcher<AndroidDeviceInfoList> m_futureWatcherRefreshDevices;
|
QFutureWatcher<AndroidDeviceInfoList> m_futureWatcherRefreshDevices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "androidqtversion.h"
|
#include "androidqtversion.h"
|
||||||
#include "androidbuildapkstep.h"
|
#include "androidbuildapkstep.h"
|
||||||
#include "androidavdmanager.h"
|
#include "androidavdmanager.h"
|
||||||
|
#include "androidsdkmanager.h"
|
||||||
|
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
@@ -174,7 +175,8 @@ QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target)
|
|||||||
if (androidBuildApkStep)
|
if (androidBuildApkStep)
|
||||||
return androidBuildApkStep->buildTargetSdk();
|
return androidBuildApkStep->buildTargetSdk();
|
||||||
|
|
||||||
QString fallback = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
|
QString fallback = AndroidConfig::apiLevelNameFor(
|
||||||
|
AndroidConfigurations::sdkManager()->latestAndroidSdkPlatform());
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,13 +48,26 @@ namespace Internal {
|
|||||||
const QVersionNumber sdkManagerIntroVersion(25, 3 ,0);
|
const QVersionNumber sdkManagerIntroVersion(25, 3 ,0);
|
||||||
|
|
||||||
const char installLocationKey[] = "Installed Location:";
|
const char installLocationKey[] = "Installed Location:";
|
||||||
const char apiLevelPropertyKey[] = "AndroidVersion.ApiLevel";
|
const char revisionKey[] = "Version:";
|
||||||
const char abiPropertyKey[] = "SystemImage.Abi";
|
const char descriptionKey[] = "Description:";
|
||||||
|
|
||||||
const int sdkManagerCmdTimeoutS = 60;
|
const int sdkManagerCmdTimeoutS = 60;
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
|
int platformNameToApiLevel(const QString &platformName)
|
||||||
|
{
|
||||||
|
int apiLevel = -1;
|
||||||
|
QRegularExpression re("(android-)(?<apiLevel>[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
|
Parses the \a line for a [spaces]key[spaces]value[spaces] pattern and returns
|
||||||
\c true if \a key is found, false otherwise. Result is copied into \a value.
|
\c true if \a key is found, false otherwise. Result is copied into \a value.
|
||||||
@@ -75,7 +88,7 @@ static bool valueForKey(QString key, const QString &line, QString *value = nullp
|
|||||||
\c true if the command is successfully executed. Output is copied into \a output. The function
|
\c true if the command is successfully executed. Output is copied into \a output. The function
|
||||||
blocks the calling thread.
|
blocks the calling thread.
|
||||||
*/
|
*/
|
||||||
static bool sdkManagerCommand(const AndroidConfig config, const QStringList &args, QString *output,
|
static bool sdkManagerCommand(const AndroidConfig &config, const QStringList &args, QString *output,
|
||||||
int timeout = sdkManagerCmdTimeoutS)
|
int timeout = sdkManagerCmdTimeoutS)
|
||||||
{
|
{
|
||||||
QString sdkManagerToolPath = config.sdkManagerToolPath().toString();
|
QString sdkManagerToolPath = config.sdkManagerToolPath().toString();
|
||||||
@@ -88,6 +101,29 @@ static bool sdkManagerCommand(const AndroidConfig config, const QStringList &arg
|
|||||||
return response.result == SynchronousProcessResponse::Finished;
|
return response.result == SynchronousProcessResponse::Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AndroidSdkManagerPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AndroidSdkManagerPrivate(AndroidSdkManager &sdkManager, const AndroidConfig &config);
|
||||||
|
~AndroidSdkManagerPrivate();
|
||||||
|
|
||||||
|
AndroidSdkPackageList filteredPackages(AndroidSdkPackage::PackageState state,
|
||||||
|
AndroidSdkPackage::PackageType type,
|
||||||
|
bool forceUpdate = false);
|
||||||
|
const AndroidSdkPackageList &allPackages(bool forceUpdate = false);
|
||||||
|
void refreshSdkPackages(bool forceReload = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reloadSdkPackages();
|
||||||
|
void clearPackages();
|
||||||
|
|
||||||
|
AndroidSdkManager &m_sdkManager;
|
||||||
|
const AndroidConfig &m_config;
|
||||||
|
AndroidSdkPackageList m_allPackages;
|
||||||
|
FileName lastSdkManagerPath;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class SdkManagerOutputParser
|
\class SdkManagerOutputParser
|
||||||
\brief The SdkManagerOutputParser class is a helper class to parse the output of the \c sdkmanager
|
\brief The SdkManagerOutputParser class is a helper class to parse the output of the \c sdkmanager
|
||||||
@@ -108,19 +144,20 @@ public:
|
|||||||
SectionMarkers = InstalledPackagesMarker | AvailablePackagesMarkers | AvailableUpdatesMarker
|
SectionMarkers = InstalledPackagesMarker | AvailablePackagesMarkers | AvailableUpdatesMarker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SdkManagerOutputParser(AndroidSdkPackageList &container) : m_packages(container) {}
|
||||||
void parsePackageListing(const QString &output);
|
void parsePackageListing(const QString &output);
|
||||||
|
|
||||||
SdkPlatformList m_installedPlatforms;
|
AndroidSdkPackageList &m_packages;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void compileData();
|
void compilePackageAssociations();
|
||||||
void parsePackageData(MarkerTag packageMarker, const QStringList &data);
|
void parsePackageData(MarkerTag packageMarker, const QStringList &data);
|
||||||
bool parsePlatform(const QStringList &data, SdkPlatform *platform) const;
|
AndroidSdkPackage *parsePlatform(const QStringList &data) const;
|
||||||
bool parseSystemImage(const QStringList &data, SystemImage *image);
|
QPair<SystemImage *, int> parseSystemImage(const QStringList &data) const;
|
||||||
MarkerTag parseMarkers(const QString &line);
|
MarkerTag parseMarkers(const QString &line);
|
||||||
|
|
||||||
MarkerTag m_currentSection = MarkerTag::None;
|
MarkerTag m_currentSection = MarkerTag::None;
|
||||||
SystemImageList m_installedSystemImages;
|
QHash<AndroidSdkPackage *, int> m_systemImages;
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::map<SdkManagerOutputParser::MarkerTag, const char *> markerTags {
|
const std::map<SdkManagerOutputParser::MarkerTag, const char *> markerTags {
|
||||||
@@ -131,9 +168,9 @@ const std::map<SdkManagerOutputParser::MarkerTag, const char *> markerTags {
|
|||||||
{SdkManagerOutputParser::MarkerTag::SystemImageMarker, "system-images"}
|
{SdkManagerOutputParser::MarkerTag::SystemImageMarker, "system-images"}
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidSdkManager::AndroidSdkManager(const AndroidConfig &config):
|
AndroidSdkManager::AndroidSdkManager(const AndroidConfig &config, QObject *parent):
|
||||||
m_config(config),
|
QObject(parent),
|
||||||
m_parser(new SdkManagerOutputParser)
|
m_d(new AndroidSdkManagerPrivate(*this, config))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,21 +179,61 @@ AndroidSdkManager::~AndroidSdkManager()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SdkPlatformList AndroidSdkManager::availableSdkPlatforms(bool *ok)
|
SdkPlatformList AndroidSdkManager::installedSdkPlatforms()
|
||||||
{
|
{
|
||||||
bool success = false;
|
AndroidSdkPackageList list = m_d->filteredPackages(AndroidSdkPackage::Installed,
|
||||||
if (m_config.sdkToolsVersion() < sdkManagerIntroVersion) {
|
AndroidSdkPackage::SdkPlatformPackage);
|
||||||
AndroidToolManager toolManager(m_config);
|
return Utils::transform(list, [](AndroidSdkPackage *p) {
|
||||||
return toolManager.availableSdkPlatforms(ok);
|
return static_cast<SdkPlatform *>(p);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QString packageListing;
|
const AndroidSdkPackageList &AndroidSdkManager::allSdkPackages()
|
||||||
if (sdkManagerCommand(m_config, QStringList({"--list", "--verbose"}), &packageListing))
|
{
|
||||||
m_parser->parsePackageListing(packageListing);
|
return m_d->allPackages();
|
||||||
|
}
|
||||||
|
|
||||||
if (ok)
|
AndroidSdkPackageList AndroidSdkManager::availableSdkPackages()
|
||||||
*ok = success;
|
{
|
||||||
return m_parser->m_installedPlatforms;
|
return m_d->filteredPackages(AndroidSdkPackage::Available, AndroidSdkPackage::AnyValidType);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSdkPackageList AndroidSdkManager::installedSdkPackages()
|
||||||
|
{
|
||||||
|
return m_d->filteredPackages(AndroidSdkPackage::Installed, AndroidSdkPackage::AnyValidType);
|
||||||
|
}
|
||||||
|
|
||||||
|
SdkPlatform *AndroidSdkManager::latestAndroidSdkPlatform(AndroidSdkPackage::PackageState state)
|
||||||
|
{
|
||||||
|
SdkPlatform *result = nullptr;
|
||||||
|
const AndroidSdkPackageList list = m_d->filteredPackages(state,
|
||||||
|
AndroidSdkPackage::SdkPlatformPackage);
|
||||||
|
for (AndroidSdkPackage *p : list) {
|
||||||
|
auto platform = static_cast<SdkPlatform *>(p);
|
||||||
|
if (!result || result->apiLevel() < platform->apiLevel())
|
||||||
|
result = platform;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SdkPlatformList AndroidSdkManager::filteredSdkPlatforms(int minApiLevel,
|
||||||
|
AndroidSdkPackage::PackageState state)
|
||||||
|
{
|
||||||
|
const AndroidSdkPackageList list = m_d->filteredPackages(state,
|
||||||
|
AndroidSdkPackage::SdkPlatformPackage);
|
||||||
|
|
||||||
|
SdkPlatformList result;
|
||||||
|
for (AndroidSdkPackage *p : list) {
|
||||||
|
auto platform = static_cast<SdkPlatform *>(p);
|
||||||
|
if (platform && platform->apiLevel() >= minApiLevel)
|
||||||
|
result << platform;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkManager::reloadPackages(bool forceReload)
|
||||||
|
{
|
||||||
|
m_d->refreshSdkPackages(forceReload);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdkManagerOutputParser::parsePackageListing(const QString &output)
|
void SdkManagerOutputParser::parsePackageListing(const QString &output)
|
||||||
@@ -173,10 +250,9 @@ void SdkManagerOutputParser::parsePackageListing(const QString &output)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QRegularExpression delimiters("[\n\r]");
|
QRegularExpression delimiters("[\\n\\r]");
|
||||||
foreach (QString outputLine, output.split(delimiters)) {
|
foreach (QString outputLine, output.split(delimiters)) {
|
||||||
MarkerTag marker = parseMarkers(outputLine.trimmed());
|
MarkerTag marker = parseMarkers(outputLine.trimmed());
|
||||||
|
|
||||||
if (marker & SectionMarkers) {
|
if (marker & SectionMarkers) {
|
||||||
// Section marker found. Update the current section being parsed.
|
// Section marker found. Update the current section being parsed.
|
||||||
m_currentSection = marker;
|
m_currentSection = marker;
|
||||||
@@ -211,20 +287,27 @@ void SdkManagerOutputParser::parsePackageListing(const QString &output)
|
|||||||
packageData << outputLine;
|
packageData << outputLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileData();
|
compilePackageAssociations();
|
||||||
Utils::sort(m_installedPlatforms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdkManagerOutputParser::compileData()
|
void SdkManagerOutputParser::compilePackageAssociations()
|
||||||
{
|
{
|
||||||
// Associate the system images with sdk platforms.
|
// Associate the system images with sdk platforms.
|
||||||
for (auto &image : m_installedSystemImages) {
|
auto imageItr = m_systemImages.cbegin();
|
||||||
auto findPlatfom = [image](const SdkPlatform &platform) {
|
while (imageItr != m_systemImages.cend()) {
|
||||||
return platform.apiLevel == image.apiLevel;
|
auto findPlatform = [imageItr](const AndroidSdkPackage *p) {
|
||||||
|
const SdkPlatform *platform = nullptr;
|
||||||
|
if (p->type() == AndroidSdkPackage::SdkPlatformPackage)
|
||||||
|
platform = static_cast<const SdkPlatform*>(p);
|
||||||
|
return platform && platform->apiLevel() == imageItr.value();
|
||||||
};
|
};
|
||||||
auto itr = std::find_if(m_installedPlatforms.begin(), m_installedPlatforms.end(), findPlatfom);
|
auto itr = std::find_if(m_packages.begin(), m_packages.end(),
|
||||||
if (itr != m_installedPlatforms.end())
|
findPlatform);
|
||||||
itr->systemImages.append(image);
|
if (itr != m_packages.end()) {
|
||||||
|
SdkPlatform *platform = static_cast<SdkPlatform*>(*itr);
|
||||||
|
platform->addSystemImage(static_cast<SystemImage *>(imageItr.key()));
|
||||||
|
}
|
||||||
|
++imageItr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,96 +318,142 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt
|
|||||||
if (m_currentSection != MarkerTag::InstalledPackagesMarker)
|
if (m_currentSection != MarkerTag::InstalledPackagesMarker)
|
||||||
return; // For now, only interested in installed packages.
|
return; // For now, only interested in installed packages.
|
||||||
|
|
||||||
|
AndroidSdkPackage *package = nullptr;
|
||||||
switch (packageMarker) {
|
switch (packageMarker) {
|
||||||
case MarkerTag::PlatformMarker:
|
case MarkerTag::PlatformMarker:
|
||||||
{
|
package = parsePlatform(data);
|
||||||
SdkPlatform platform;
|
if (package)
|
||||||
if (parsePlatform(data, &platform))
|
m_packages.append(package);
|
||||||
m_installedPlatforms.append(platform);
|
|
||||||
else
|
|
||||||
qCDebug(sdkManagerLog) << "Platform: Parsing failed: " << data;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MarkerTag::SystemImageMarker:
|
case MarkerTag::SystemImageMarker:
|
||||||
{
|
{
|
||||||
SystemImage image;
|
QPair<SystemImage *, int> result = parseSystemImage(data);
|
||||||
if (parseSystemImage(data, &image))
|
if (result.first) {
|
||||||
m_installedSystemImages.append(image);
|
m_systemImages[result.first] = result.second;
|
||||||
else
|
package = result.first;
|
||||||
|
} else {
|
||||||
qCDebug(sdkManagerLog) << "System Image: Parsing failed: " << data;
|
qCDebug(sdkManagerLog) << "System Image: Parsing failed: " << data;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qCDebug(sdkManagerLog) << "Unhandled package: " << markerTags.at(packageMarker);
|
qCDebug(sdkManagerLog) << "Unhandled package: " << markerTags.at(packageMarker);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (package) {
|
||||||
|
switch (m_currentSection) {
|
||||||
|
case MarkerTag::InstalledPackagesMarker:
|
||||||
|
package->setState(AndroidSdkPackage::Installed);
|
||||||
|
break;
|
||||||
|
case MarkerTag::AvailablePackagesMarkers:
|
||||||
|
case MarkerTag::AvailableUpdatesMarker:
|
||||||
|
package->setState(AndroidSdkPackage::Available);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCDebug(sdkManagerLog) << "Invalid section marker: " << markerTags.at(m_currentSection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdkManagerOutputParser::parsePlatform(const QStringList &data, SdkPlatform *platform) const
|
AndroidSdkPackage *SdkManagerOutputParser::parsePlatform(const QStringList &data) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(platform && !data.isEmpty(), return false);
|
QTC_ASSERT(!data.isEmpty(), qCDebug(sdkManagerLog) << "Platform: Empty input"; return nullptr);
|
||||||
|
|
||||||
QStringList parts = data.at(0).split(';');
|
QStringList parts = data.at(0).split(';');
|
||||||
if (parts.count() < 2) {
|
QTC_ASSERT(parts.count() >= 2,
|
||||||
qCDebug(sdkManagerLog) << "Platform: Unexpected header: "<< data;
|
qCDebug(sdkManagerLog) << "Platform: Unexpected header:"<< data; return nullptr);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
platform->name = parts[1];
|
|
||||||
platform->package = data.at(0);
|
|
||||||
|
|
||||||
foreach (QString line, data) {
|
int apiLevel = platformNameToApiLevel(parts.at(1));
|
||||||
QString value;
|
if (apiLevel == -1) {
|
||||||
if (valueForKey(installLocationKey, line, &value))
|
|
||||||
platform->installedLocation = Utils::FileName::fromString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int apiLevel = AndroidManager::findApiLevel(platform->installedLocation);
|
|
||||||
if (apiLevel != -1)
|
|
||||||
platform->apiLevel = apiLevel;
|
|
||||||
else
|
|
||||||
qCDebug(sdkManagerLog) << "Platform: Can not parse api level:"<< data;
|
qCDebug(sdkManagerLog) << "Platform: Can not parse api level:"<< data;
|
||||||
|
return nullptr;
|
||||||
return apiLevel != -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdkManagerOutputParser::parseSystemImage(const QStringList &data, SystemImage *image)
|
QVersionNumber revision;
|
||||||
{
|
QString description;
|
||||||
QTC_ASSERT(image && !data.isEmpty(), return false);
|
Utils::FileName installedLocation;
|
||||||
|
|
||||||
QStringList parts = data.at(0).split(';');
|
|
||||||
QTC_ASSERT(!data.isEmpty() && parts.count() >= 4,
|
|
||||||
qCDebug(sdkManagerLog) << "System Image: Unexpected header: " << data);
|
|
||||||
|
|
||||||
image->package = data.at(0);
|
|
||||||
foreach (QString line, data) {
|
foreach (QString line, data) {
|
||||||
QString value;
|
QString value;
|
||||||
if (valueForKey(installLocationKey, line, &value))
|
if (valueForKey(installLocationKey, line, &value)) {
|
||||||
image->installedLocation = Utils::FileName::fromString(value);
|
installedLocation = Utils::FileName::fromString(value);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::FileName propertiesPath = image->installedLocation;
|
if (valueForKey(revisionKey, line, &value)) {
|
||||||
propertiesPath.appendPath("/source.properties");
|
revision = QVersionNumber::fromString(value);
|
||||||
if (propertiesPath.exists()) {
|
continue;
|
||||||
// Installed System Image.
|
|
||||||
QSettings imageProperties(propertiesPath.toString(), QSettings::IniFormat);
|
|
||||||
bool validApiLevel = false;
|
|
||||||
image->apiLevel = imageProperties.value(apiLevelPropertyKey).toInt(&validApiLevel);
|
|
||||||
if (!validApiLevel) {
|
|
||||||
qCDebug(sdkManagerLog) << "System Image: Can not parse api level: "<< data;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
image->abiName = imageProperties.value(abiPropertyKey).toString();
|
|
||||||
} else if (parts.count() >= 4){
|
if (valueForKey(descriptionKey, line, &value)) {
|
||||||
image->apiLevel = parts[1].section('-', 1, 1).toInt();
|
description = value;
|
||||||
image->abiName = parts[3];
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SdkPlatform *platform = nullptr;
|
||||||
|
if (!revision.isNull() && apiLevel != -1) {
|
||||||
|
platform = new SdkPlatform(revision, data.at(0), apiLevel);
|
||||||
|
platform->setDescriptionText(description);
|
||||||
|
platform->setInstalledLocation(installedLocation);
|
||||||
|
} else {
|
||||||
|
qCDebug(sdkManagerLog) << "Platform: Parsing failed. Minimum required data unavailable:"
|
||||||
|
<< data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPair<SystemImage *, int> SdkManagerOutputParser::parseSystemImage(const QStringList &data) const
|
||||||
|
{
|
||||||
|
QPair <SystemImage *, int> result(nullptr, -1);
|
||||||
|
QTC_ASSERT(!data.isEmpty(),
|
||||||
|
qCDebug(sdkManagerLog) << "System Image: Empty input"; return result);
|
||||||
|
|
||||||
|
QStringList parts = data.at(0).split(';');
|
||||||
|
QTC_ASSERT(parts.count() >= 4,
|
||||||
|
qCDebug(sdkManagerLog) << "System Image: Unexpected header:" << data; return result);
|
||||||
|
|
||||||
|
int apiLevel = platformNameToApiLevel(parts.at(1));
|
||||||
|
if (apiLevel == -1) {
|
||||||
|
qCDebug(sdkManagerLog) << "System Image: Can not parse api level:"<< data;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVersionNumber revision;
|
||||||
|
QString description;
|
||||||
|
Utils::FileName installedLocation;
|
||||||
|
foreach (QString line, data) {
|
||||||
|
QString value;
|
||||||
|
if (valueForKey(installLocationKey, line, &value)) {
|
||||||
|
installedLocation = Utils::FileName::fromString(value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueForKey(revisionKey, line, &value)) {
|
||||||
|
revision = QVersionNumber::fromString(value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueForKey(descriptionKey, line, &value)) {
|
||||||
|
description = value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!revision.isNull()) {
|
||||||
|
auto image = new SystemImage(revision, data.at(0), parts.at(3));
|
||||||
|
image->setInstalledLocation(installedLocation);
|
||||||
|
image->setDisplayText(description);
|
||||||
|
image->setDescriptionText(description);
|
||||||
|
result = qMakePair(image, apiLevel);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(sdkManagerLog) << "System Image: Can not parse: "<< data;
|
qCDebug(sdkManagerLog) << "System Image: Can not parse: "<< data;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QString &line)
|
SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QString &line)
|
||||||
@@ -340,5 +469,79 @@ SdkManagerOutputParser::MarkerTag SdkManagerOutputParser::parseMarkers(const QSt
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidSdkManagerPrivate::AndroidSdkManagerPrivate(AndroidSdkManager &sdkManager,
|
||||||
|
const AndroidConfig &config):
|
||||||
|
m_sdkManager(sdkManager),
|
||||||
|
m_config(config)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSdkManagerPrivate::~AndroidSdkManagerPrivate()
|
||||||
|
{
|
||||||
|
clearPackages();
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSdkPackageList
|
||||||
|
AndroidSdkManagerPrivate::filteredPackages(AndroidSdkPackage::PackageState state,
|
||||||
|
AndroidSdkPackage::PackageType type, bool forceUpdate)
|
||||||
|
{
|
||||||
|
refreshSdkPackages(forceUpdate);
|
||||||
|
return Utils::filtered(m_allPackages, [state, type](const AndroidSdkPackage *p) {
|
||||||
|
return p->state() & state && p->type() & type;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const AndroidSdkPackageList &AndroidSdkManagerPrivate::allPackages(bool forceUpdate)
|
||||||
|
{
|
||||||
|
refreshSdkPackages(forceUpdate);
|
||||||
|
return m_allPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkManagerPrivate::reloadSdkPackages()
|
||||||
|
{
|
||||||
|
m_sdkManager.packageReloadBegin();
|
||||||
|
clearPackages();
|
||||||
|
|
||||||
|
lastSdkManagerPath = m_config.sdkManagerToolPath();
|
||||||
|
|
||||||
|
if (m_config.sdkToolsVersion().isNull()) {
|
||||||
|
// Configuration has invalid sdk path or corrupt installation.
|
||||||
|
m_sdkManager.packageReloadFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_config.sdkToolsVersion() < sdkManagerIntroVersion) {
|
||||||
|
// Old Sdk tools.
|
||||||
|
AndroidToolManager toolManager(m_config);
|
||||||
|
auto toAndroidSdkPackages = [](SdkPlatform *p) -> AndroidSdkPackage *{
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
m_allPackages = Utils::transform(toolManager.availableSdkPlatforms(), toAndroidSdkPackages);
|
||||||
|
} else {
|
||||||
|
QString packageListing;
|
||||||
|
if (sdkManagerCommand(m_config, QStringList({"--list", "--verbose"}), &packageListing)) {
|
||||||
|
SdkManagerOutputParser parser(m_allPackages);
|
||||||
|
parser.parsePackageListing(packageListing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_sdkManager.packageReloadFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkManagerPrivate::refreshSdkPackages(bool forceReload)
|
||||||
|
{
|
||||||
|
// Sdk path changed. Updated packages.
|
||||||
|
// QTC updates the package listing only
|
||||||
|
if (m_config.sdkManagerToolPath() != lastSdkManagerPath || forceReload)
|
||||||
|
reloadSdkPackages();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkManagerPrivate::clearPackages()
|
||||||
|
{
|
||||||
|
for (AndroidSdkPackage *p : m_allPackages)
|
||||||
|
delete p;
|
||||||
|
m_allPackages.clear();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Android
|
} // namespace Android
|
||||||
|
|||||||
@@ -25,26 +25,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utils/fileutils.h"
|
#include "utils/fileutils.h"
|
||||||
#include "androidconfigurations.h"
|
#include "androidsdkpackage.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace Android {
|
namespace Android {
|
||||||
|
|
||||||
|
class AndroidConfig;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class SdkManagerOutputParser;
|
class AndroidSdkManagerPrivate;
|
||||||
|
|
||||||
class AndroidSdkManager
|
class AndroidSdkManager : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AndroidSdkManager(const AndroidConfig &config);
|
AndroidSdkManager(const AndroidConfig &config, QObject *parent = nullptr);
|
||||||
~AndroidSdkManager();
|
~AndroidSdkManager();
|
||||||
|
|
||||||
SdkPlatformList availableSdkPlatforms(bool *ok = nullptr);
|
SdkPlatformList installedSdkPlatforms();
|
||||||
|
const AndroidSdkPackageList &allSdkPackages();
|
||||||
|
AndroidSdkPackageList availableSdkPackages();
|
||||||
|
AndroidSdkPackageList installedSdkPackages();
|
||||||
|
|
||||||
|
SdkPlatform *latestAndroidSdkPlatform(AndroidSdkPackage::PackageState state
|
||||||
|
= AndroidSdkPackage::Installed);
|
||||||
|
SdkPlatformList filteredSdkPlatforms(int minApiLevel,
|
||||||
|
AndroidSdkPackage::PackageState state
|
||||||
|
= AndroidSdkPackage::Installed);
|
||||||
|
void reloadPackages(bool forceReload = false);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void packageReloadBegin();
|
||||||
|
void packageReloadFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const AndroidConfig &m_config;
|
std::unique_ptr<AndroidSdkManagerPrivate> m_d;
|
||||||
std::unique_ptr<SdkManagerOutputParser> m_parser;
|
friend class AndroidSdkManagerPrivate;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
193
src/plugins/android/androidsdkpackage.cpp
Normal file
193
src/plugins/android/androidsdkpackage.cpp
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2017 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#include "androidsdkpackage.h"
|
||||||
|
|
||||||
|
namespace Android {
|
||||||
|
|
||||||
|
AndroidSdkPackage::AndroidSdkPackage(QVersionNumber version, QString sdkStylePathStr,
|
||||||
|
QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_revision(version),
|
||||||
|
m_sdkStylePath(sdkStylePathStr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AndroidSdkPackage::operator <(const AndroidSdkPackage &other) const
|
||||||
|
{
|
||||||
|
if (typeid(*this) != typeid(other))
|
||||||
|
return type() < other.type();
|
||||||
|
return displayText() < other.displayText();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AndroidSdkPackage::displayText() const
|
||||||
|
{
|
||||||
|
return m_displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AndroidSdkPackage::descriptionText() const
|
||||||
|
{
|
||||||
|
return m_descriptionText;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVersionNumber &AndroidSdkPackage::revision() const
|
||||||
|
{
|
||||||
|
return m_revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSdkPackage::PackageState AndroidSdkPackage::state() const
|
||||||
|
{
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &AndroidSdkPackage::sdkStylePath() const
|
||||||
|
{
|
||||||
|
return m_sdkStylePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Utils::FileName &AndroidSdkPackage::installedLocation() const
|
||||||
|
{
|
||||||
|
return m_installedLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkPackage::setDisplayText(const QString &str)
|
||||||
|
{
|
||||||
|
m_displayText = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkPackage::setDescriptionText(const QString &str)
|
||||||
|
{
|
||||||
|
m_descriptionText = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkPackage::setState(AndroidSdkPackage::PackageState state)
|
||||||
|
{
|
||||||
|
m_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkPackage::setInstalledLocation(const Utils::FileName &path)
|
||||||
|
{
|
||||||
|
m_installedLocation = path;
|
||||||
|
if (m_installedLocation.exists())
|
||||||
|
updatePackageDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSdkPackage::updatePackageDetails()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemImage::SystemImage(QVersionNumber version, QString sdkStylePathStr, QString abi,
|
||||||
|
SdkPlatform *platform):
|
||||||
|
AndroidSdkPackage(version, sdkStylePathStr, platform),
|
||||||
|
m_platform(platform),
|
||||||
|
m_abiName(abi)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SystemImage::isValid() const
|
||||||
|
{
|
||||||
|
return m_platform && m_platform->isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSdkPackage::PackageType SystemImage::type() const
|
||||||
|
{
|
||||||
|
return SystemImagePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &SystemImage::abiName() const
|
||||||
|
{
|
||||||
|
return m_abiName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SdkPlatform *SystemImage::platform() const
|
||||||
|
{
|
||||||
|
return m_platform.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemImage::setPlatform(SdkPlatform *platform)
|
||||||
|
{
|
||||||
|
m_platform = platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
SdkPlatform::SdkPlatform(QVersionNumber version, QString sdkStylePathStr, int api, QObject *parent) :
|
||||||
|
AndroidSdkPackage(version, sdkStylePathStr, parent),
|
||||||
|
m_apiLevel(api)
|
||||||
|
{
|
||||||
|
setDisplayText(QString("android-%1")
|
||||||
|
.arg(m_apiLevel != -1 ? QString::number(m_apiLevel) : "Unknown"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SdkPlatform::~SdkPlatform()
|
||||||
|
{
|
||||||
|
for (SystemImage *image : m_systemImages)
|
||||||
|
delete image;
|
||||||
|
m_systemImages.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SdkPlatform::isValid() const
|
||||||
|
{
|
||||||
|
return m_apiLevel != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSdkPackage::PackageType SdkPlatform::type() const
|
||||||
|
{
|
||||||
|
return SdkPlatformPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SdkPlatform::operator <(const AndroidSdkPackage &other) const
|
||||||
|
{
|
||||||
|
if (typeid(*this) != typeid(other))
|
||||||
|
return AndroidSdkPackage::operator <(other);
|
||||||
|
|
||||||
|
const SdkPlatform &platform = static_cast<const SdkPlatform &>(other);
|
||||||
|
if (platform.m_apiLevel == m_apiLevel)
|
||||||
|
return AndroidSdkPackage::operator <(other);
|
||||||
|
|
||||||
|
return platform.m_apiLevel < m_apiLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SdkPlatform::apiLevel() const
|
||||||
|
{
|
||||||
|
return m_apiLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVersionNumber SdkPlatform::version() const
|
||||||
|
{
|
||||||
|
return m_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SdkPlatform::addSystemImage(SystemImage *image)
|
||||||
|
{
|
||||||
|
m_systemImages.append(image);
|
||||||
|
image->setPlatform(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SystemImageList &SdkPlatform::systemImages() const
|
||||||
|
{
|
||||||
|
return m_systemImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Android
|
||||||
150
src/plugins/android/androidsdkpackage.h
Normal file
150
src/plugins/android/androidsdkpackage.h
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2017 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#include "utils/fileutils.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QVersionNumber>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Android {
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
class SdkManagerOutputParser;
|
||||||
|
class AndroidToolOutputParser;
|
||||||
|
}
|
||||||
|
class SdkPlatform;
|
||||||
|
class SystemImage;
|
||||||
|
|
||||||
|
class AndroidSdkPackage : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum PackageType {
|
||||||
|
UnknownPackage = 1 << 0,
|
||||||
|
SdkToolsPackage = 1 << 1,
|
||||||
|
BuildToolsPackage = 1 << 2,
|
||||||
|
PlatformToolsPackage = 1 << 3,
|
||||||
|
SdkPlatformPackage = 1 << 4,
|
||||||
|
SystemImagePackage = 1 << 5,
|
||||||
|
AnyValidType = SdkToolsPackage | BuildToolsPackage | PlatformToolsPackage |
|
||||||
|
SdkPlatformPackage | SystemImagePackage
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PackageState {
|
||||||
|
Unknown = 1 << 0,
|
||||||
|
Installed = 1 << 1,
|
||||||
|
Available = 1 << 2,
|
||||||
|
AnyValidState = Installed | Available
|
||||||
|
};
|
||||||
|
|
||||||
|
AndroidSdkPackage(QVersionNumber revision, QString sdkStylePathStr, QObject *parent = nullptr);
|
||||||
|
virtual ~AndroidSdkPackage() { }
|
||||||
|
|
||||||
|
virtual bool isValid() const = 0;
|
||||||
|
virtual PackageType type() const = 0;
|
||||||
|
virtual bool operator <(const AndroidSdkPackage &other) const;
|
||||||
|
|
||||||
|
QString displayText() const;
|
||||||
|
QString descriptionText() const;
|
||||||
|
const QVersionNumber &revision() const;
|
||||||
|
PackageState state() const;
|
||||||
|
const QString &sdkStylePath() const;
|
||||||
|
const Utils::FileName &installedLocation() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setDisplayText(const QString &str);
|
||||||
|
void setDescriptionText(const QString &str);
|
||||||
|
void setState(PackageState state);
|
||||||
|
void setInstalledLocation(const Utils::FileName &path);
|
||||||
|
|
||||||
|
virtual void updatePackageDetails();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_displayText;
|
||||||
|
QString m_descriptionText;
|
||||||
|
QVersionNumber m_revision;
|
||||||
|
PackageState m_state = PackageState::Unknown;
|
||||||
|
QString m_sdkStylePath;
|
||||||
|
Utils::FileName m_installedLocation;
|
||||||
|
|
||||||
|
friend class Internal::SdkManagerOutputParser;
|
||||||
|
friend class Internal::AndroidToolOutputParser;
|
||||||
|
};
|
||||||
|
using AndroidSdkPackageList = QList<AndroidSdkPackage*>;
|
||||||
|
|
||||||
|
class SystemImage : public AndroidSdkPackage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SystemImage(QVersionNumber revision, QString sdkStylePathStr, QString abi,
|
||||||
|
SdkPlatform *platform = nullptr);
|
||||||
|
|
||||||
|
// AndroidSdkPackage Overrides
|
||||||
|
bool isValid() const override;
|
||||||
|
PackageType type() const override;
|
||||||
|
|
||||||
|
const QString &abiName() const;
|
||||||
|
const SdkPlatform *platform() const;
|
||||||
|
void setPlatform(SdkPlatform *platform);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<SdkPlatform> m_platform;
|
||||||
|
QString m_abiName;
|
||||||
|
};
|
||||||
|
using SystemImageList = QList<SystemImage*>;
|
||||||
|
|
||||||
|
|
||||||
|
class SdkPlatform : public AndroidSdkPackage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SdkPlatform(QVersionNumber revision, QString sdkStylePathStr, int api,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
~SdkPlatform();
|
||||||
|
|
||||||
|
// AndroidSdkPackage Overrides
|
||||||
|
bool isValid() const override;
|
||||||
|
PackageType type() const override;
|
||||||
|
bool operator <(const AndroidSdkPackage &other) const override;
|
||||||
|
|
||||||
|
int apiLevel() const;
|
||||||
|
QVersionNumber version() const;
|
||||||
|
void addSystemImage(SystemImage *image);
|
||||||
|
const SystemImageList &systemImages() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SystemImageList m_systemImages;
|
||||||
|
int m_apiLevel = -1;
|
||||||
|
QVersionNumber m_version;
|
||||||
|
};
|
||||||
|
using SdkPlatformList = QList<SdkPlatform*>;
|
||||||
|
} // namespace Android
|
||||||
|
|
||||||
|
|
||||||
@@ -31,6 +31,8 @@
|
|||||||
#include "androidconstants.h"
|
#include "androidconstants.h"
|
||||||
#include "androidtoolchain.h"
|
#include "androidtoolchain.h"
|
||||||
#include "androidavdmanager.h"
|
#include "androidavdmanager.h"
|
||||||
|
#include "androidsdkmanager.h"
|
||||||
|
#include "avddialog.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
@@ -212,7 +214,8 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
|
|||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
m_ui(new Ui_AndroidSettingsWidget),
|
m_ui(new Ui_AndroidSettingsWidget),
|
||||||
m_androidConfig(AndroidConfigurations::currentConfig()),
|
m_androidConfig(AndroidConfigurations::currentConfig()),
|
||||||
m_avdManager(new AndroidAvdManager(m_androidConfig))
|
m_avdManager(new AndroidAvdManager(m_androidConfig)),
|
||||||
|
m_sdkManager(new AndroidSdkManager(m_androidConfig))
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
@@ -390,7 +393,7 @@ void AndroidSettingsWidget::validateSdk()
|
|||||||
summaryWidget->setPointValid(BuildToolsInstalledRow,
|
summaryWidget->setPointValid(BuildToolsInstalledRow,
|
||||||
!m_androidConfig.buildToolsVersion().isNull());
|
!m_androidConfig.buildToolsVersion().isNull());
|
||||||
summaryWidget->setPointValid(PlatformSdkInstalledRow,
|
summaryWidget->setPointValid(PlatformSdkInstalledRow,
|
||||||
!m_androidConfig.sdkTargets().isEmpty());
|
!m_sdkManager->installedSdkPlatforms().isEmpty());
|
||||||
updateUI();
|
updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,9 +415,9 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl()
|
|||||||
void AndroidSettingsWidget::addAVD()
|
void AndroidSettingsWidget::addAVD()
|
||||||
{
|
{
|
||||||
disableAvdControls();
|
disableAvdControls();
|
||||||
AndroidConfig::CreateAvdInfo info = m_androidConfig.gatherCreateAVDInfo(this);
|
CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, m_sdkManager.get());
|
||||||
|
|
||||||
if (!info.target.isValid()) {
|
if (!info.isValid()) {
|
||||||
enableAvdControls();
|
enableAvdControls();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -424,7 +427,7 @@ void AndroidSettingsWidget::addAVD()
|
|||||||
|
|
||||||
void AndroidSettingsWidget::avdAdded()
|
void AndroidSettingsWidget::avdAdded()
|
||||||
{
|
{
|
||||||
AndroidConfig::CreateAvdInfo info = m_futureWatcher.result();
|
CreateAvdInfo info = m_futureWatcher.result();
|
||||||
if (!info.error.isEmpty()) {
|
if (!info.error.isEmpty()) {
|
||||||
enableAvdControls();
|
enableAvdControls();
|
||||||
QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
|
QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
|
||||||
|
|||||||
@@ -100,11 +100,12 @@ private:
|
|||||||
Ui_AndroidSettingsWidget *m_ui;
|
Ui_AndroidSettingsWidget *m_ui;
|
||||||
AndroidConfig m_androidConfig;
|
AndroidConfig m_androidConfig;
|
||||||
AvdModel m_AVDModel;
|
AvdModel m_AVDModel;
|
||||||
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher;
|
QFutureWatcher<CreateAvdInfo> m_futureWatcher;
|
||||||
|
|
||||||
QFutureWatcher<AndroidDeviceInfoList> m_virtualDevicesWatcher;
|
QFutureWatcher<AndroidDeviceInfoList> m_virtualDevicesWatcher;
|
||||||
QString m_lastAddedAvd;
|
QString m_lastAddedAvd;
|
||||||
std::unique_ptr<AndroidAvdManager> m_avdManager;
|
std::unique_ptr<AndroidAvdManager> m_avdManager;
|
||||||
|
std::unique_ptr<AndroidSdkManager> m_sdkManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class AndroidToolOutputParser
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void parseTargetListing(const QString &output, const FileName &sdkLocation,
|
void parseTargetListing(const QString &output, const FileName &sdkLocation,
|
||||||
SdkPlatformList *platformList);
|
SdkPlatformList &platformList);
|
||||||
|
|
||||||
QList<SdkPlatform> m_installedPlatforms;
|
QList<SdkPlatform> m_installedPlatforms;
|
||||||
};
|
};
|
||||||
@@ -104,7 +104,7 @@ SdkPlatformList AndroidToolManager::availableSdkPlatforms(bool *ok) const
|
|||||||
QString targetListing;
|
QString targetListing;
|
||||||
if (androidToolCommand(m_config.androidToolPath(), QStringList({"list", "target"}),
|
if (androidToolCommand(m_config.androidToolPath(), QStringList({"list", "target"}),
|
||||||
androidToolEnvironment(), &targetListing)) {
|
androidToolEnvironment(), &targetListing)) {
|
||||||
m_parser->parseTargetListing(targetListing, m_config.sdkLocation(), &list);
|
m_parser->parseTargetListing(targetListing, m_config.sdkLocation(), list);
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
qCDebug(androidToolLog) << "Android tool target listing failed";
|
qCDebug(androidToolLog) << "Android tool target listing failed";
|
||||||
@@ -121,8 +121,7 @@ void AndroidToolManager::launchAvdManager() const
|
|||||||
QProcess::startDetached(m_config.androidToolPath().toString(), QStringList("avd"));
|
QProcess::startDetached(m_config.androidToolPath().toString(), QStringList("avd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<AndroidConfig::CreateAvdInfo>
|
QFuture<CreateAvdInfo> AndroidToolManager::createAvd(CreateAvdInfo info) const
|
||||||
AndroidToolManager::createAvd(AndroidConfig::CreateAvdInfo info) const
|
|
||||||
{
|
{
|
||||||
return Utils::runAsync(&AndroidToolManager::createAvdImpl, info,
|
return Utils::runAsync(&AndroidToolManager::createAvdImpl, info,
|
||||||
m_config.androidToolPath(), androidToolEnvironment());
|
m_config.androidToolPath(), androidToolEnvironment());
|
||||||
@@ -159,15 +158,14 @@ Environment AndroidToolManager::androidToolEnvironment() const
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidConfig::CreateAvdInfo AndroidToolManager::createAvdImpl(AndroidConfig::CreateAvdInfo info,
|
CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FileName androidToolPath,
|
||||||
FileName androidToolPath,
|
|
||||||
Environment env)
|
Environment env)
|
||||||
{
|
{
|
||||||
QProcess proc;
|
QProcess proc;
|
||||||
proc.setProcessEnvironment(env.toProcessEnvironment());
|
proc.setProcessEnvironment(env.toProcessEnvironment());
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
arguments << QLatin1String("create") << QLatin1String("avd")
|
arguments << QLatin1String("create") << QLatin1String("avd")
|
||||||
<< QLatin1String("-t") << AndroidConfig::apiLevelNameFor(info.target)
|
<< QLatin1String("-t") << AndroidConfig::apiLevelNameFor(info.sdkPlatform)
|
||||||
<< QLatin1String("-n") << info.name
|
<< QLatin1String("-n") << info.name
|
||||||
<< QLatin1String("-b") << info.abi;
|
<< QLatin1String("-b") << info.abi;
|
||||||
if (info.sdcardSize > 0)
|
if (info.sdcardSize > 0)
|
||||||
@@ -293,24 +291,36 @@ AndroidDeviceInfoList AndroidToolManager::androidVirtualDevices(const Utils::Fil
|
|||||||
|
|
||||||
void AndroidToolOutputParser::parseTargetListing(const QString &output,
|
void AndroidToolOutputParser::parseTargetListing(const QString &output,
|
||||||
const Utils::FileName &sdkLocation,
|
const Utils::FileName &sdkLocation,
|
||||||
SdkPlatformList *platformList)
|
SdkPlatformList &platformList)
|
||||||
{
|
{
|
||||||
if (!platformList)
|
auto addSystemImage = [](const QStringList& abiList, SdkPlatform *platform) {
|
||||||
return;
|
QTC_ASSERT(platform, return);
|
||||||
|
|
||||||
auto addSystemImage = [](const QStringList& abiList, SdkPlatform &platform) {
|
|
||||||
foreach (auto imageAbi, abiList) {
|
foreach (auto imageAbi, abiList) {
|
||||||
SystemImage image;
|
auto image = new SystemImage(QVersionNumber(), "", imageAbi, platform);
|
||||||
image.abiName = imageAbi;
|
platform->addSystemImage(image);
|
||||||
image.apiLevel = platform.apiLevel;
|
|
||||||
platform.systemImages.append(image);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SdkPlatform platform;
|
class {
|
||||||
|
public:
|
||||||
QStringList abiList;
|
QStringList abiList;
|
||||||
foreach (const QString &l, output.split('\n')) {
|
QVersionNumber revision;
|
||||||
const QString line = l.trimmed();
|
int apiLevel = -1;
|
||||||
|
QString description;
|
||||||
|
Utils::FileName installedLocation;
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
abiList.clear();
|
||||||
|
revision = QVersionNumber();
|
||||||
|
apiLevel = -1;
|
||||||
|
description.clear();
|
||||||
|
installedLocation.clear();
|
||||||
|
}
|
||||||
|
} platformParams;
|
||||||
|
|
||||||
|
QStringList outputLines = output.split('\n');
|
||||||
|
for (int index = 0; index < outputLines.count(); ++index) {
|
||||||
|
const QString line = outputLines.at(index).trimmed();
|
||||||
if (line.startsWith(QLatin1String("id:")) && line.contains(QLatin1String("android-"))) {
|
if (line.startsWith(QLatin1String("id:")) && line.contains(QLatin1String("android-"))) {
|
||||||
int index = line.indexOf(QLatin1String("\"android-"));
|
int index = line.indexOf(QLatin1String("\"android-"));
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
@@ -319,33 +329,33 @@ void AndroidToolOutputParser::parseTargetListing(const QString &output,
|
|||||||
const QString tmp = androidTarget.mid(androidTarget.lastIndexOf(QLatin1Char('-')) + 1);
|
const QString tmp = androidTarget.mid(androidTarget.lastIndexOf(QLatin1Char('-')) + 1);
|
||||||
Utils::FileName platformPath = sdkLocation;
|
Utils::FileName platformPath = sdkLocation;
|
||||||
platformPath.appendPath(QString("/platforms/android-%1").arg(tmp));
|
platformPath.appendPath(QString("/platforms/android-%1").arg(tmp));
|
||||||
platform.installedLocation = platformPath;
|
platformParams.installedLocation = platformPath;
|
||||||
platform.apiLevel = AndroidManager::findApiLevel(platformPath);
|
platformParams.apiLevel = AndroidManager::findApiLevel(platformPath);
|
||||||
} else if (line.startsWith(QLatin1String("Name:"))) {
|
} else if (line.startsWith(QLatin1String("Name:"))) {
|
||||||
platform.name = line.mid(6);
|
platformParams.description = line.mid(6);
|
||||||
|
} else if (line.startsWith(QLatin1String("Revision:"))) {
|
||||||
|
platformParams.revision = QVersionNumber::fromString(line.mid(10));
|
||||||
} else if (line.startsWith(QLatin1String("Tag/ABIs :"))) {
|
} else if (line.startsWith(QLatin1String("Tag/ABIs :"))) {
|
||||||
abiList = cleanAndroidABIs(line.mid(10).trimmed().split(QLatin1String(", ")));
|
platformParams.abiList = cleanAndroidABIs(line.mid(10).trimmed().split(QLatin1String(", ")));
|
||||||
} else if (line.startsWith(QLatin1String("ABIs"))) {
|
} else if (line.startsWith(QLatin1String("ABIs"))) {
|
||||||
abiList = cleanAndroidABIs(line.mid(6).trimmed().split(QLatin1String(", ")));
|
platformParams.abiList = cleanAndroidABIs(line.mid(6).trimmed().split(QLatin1String(", ")));
|
||||||
} else if (line.startsWith(QLatin1String("---")) || line.startsWith(QLatin1String("==="))) {
|
} else if (line.startsWith(QLatin1String("---"))
|
||||||
if (platform.apiLevel == -1)
|
|| line.startsWith(QLatin1String("==="))
|
||||||
|
|| index == outputLines.count() - 1) {
|
||||||
|
if (platformParams.apiLevel == -1)
|
||||||
continue;
|
continue;
|
||||||
|
auto platform = new SdkPlatform(platformParams.revision,
|
||||||
addSystemImage(abiList, platform);
|
QString("platforms;android-%1").arg(platformParams.apiLevel),
|
||||||
*platformList << platform;
|
platformParams.apiLevel);
|
||||||
|
platform->setState(AndroidSdkPackage::Installed);
|
||||||
platform = SdkPlatform();
|
platform->setDescriptionText(platformParams.description);
|
||||||
abiList.clear();
|
platform->setInstalledLocation(platformParams.installedLocation);
|
||||||
|
addSystemImage(platformParams.abiList, platform);
|
||||||
|
platformList << platform;
|
||||||
|
platformParams.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Utils::sort(platformList);
|
||||||
// The last parsed Platform.
|
|
||||||
if (platform.apiLevel != -1) {
|
|
||||||
addSystemImage(abiList, platform);
|
|
||||||
*platformList << platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::sort(*platformList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -51,15 +51,15 @@ public:
|
|||||||
SdkPlatformList availableSdkPlatforms(bool *ok = nullptr) const;
|
SdkPlatformList availableSdkPlatforms(bool *ok = nullptr) const;
|
||||||
void launchAvdManager() const;
|
void launchAvdManager() const;
|
||||||
|
|
||||||
QFuture<AndroidConfig::CreateAvdInfo> createAvd(AndroidConfig::CreateAvdInfo info) const;
|
QFuture<CreateAvdInfo> createAvd(CreateAvdInfo info) const;
|
||||||
bool removeAvd(const QString &name) const;
|
bool removeAvd(const QString &name) const;
|
||||||
QFuture<AndroidDeviceInfoList> androidVirtualDevicesFuture() const;
|
QFuture<AndroidDeviceInfoList> androidVirtualDevicesFuture() const;
|
||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
private:
|
private:
|
||||||
Utils::Environment androidToolEnvironment() const;
|
Utils::Environment androidToolEnvironment() const;
|
||||||
static AndroidConfig::CreateAvdInfo createAvdImpl(AndroidConfig::CreateAvdInfo info,
|
static CreateAvdInfo createAvdImpl(CreateAvdInfo info, Utils::FileName androidToolPath,
|
||||||
Utils::FileName androidToolPath, Utils::Environment env);
|
Utils::Environment env);
|
||||||
static AndroidDeviceInfoList androidVirtualDevices(const Utils::FileName &androidTool,
|
static AndroidDeviceInfoList androidVirtualDevices(const Utils::FileName &androidTool,
|
||||||
const Utils::FileName &sdkLlocationPath,
|
const Utils::FileName &sdkLlocationPath,
|
||||||
const Utils::Environment &environment);
|
const Utils::Environment &environment);
|
||||||
|
|||||||
@@ -24,11 +24,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "avddialog.h"
|
#include "avddialog.h"
|
||||||
#include "androidconfigurations.h"
|
#include "androidsdkmanager.h"
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/tooltip/tooltip.h>
|
#include <utils/tooltip/tooltip.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@@ -37,10 +38,14 @@
|
|||||||
using namespace Android;
|
using namespace Android;
|
||||||
using namespace Android::Internal;
|
using namespace Android::Internal;
|
||||||
|
|
||||||
AvdDialog::AvdDialog(int minApiLevel, const QString &targetArch, const AndroidConfig *config, QWidget *parent) :
|
AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QString &targetArch,
|
||||||
QDialog(parent), m_config(config), m_minApiLevel(minApiLevel),
|
QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
m_sdkManager(sdkManager),
|
||||||
|
m_minApiLevel(minApiLevel),
|
||||||
m_allowedNameChars(QLatin1String("[a-z|A-Z|0-9|._-]*"))
|
m_allowedNameChars(QLatin1String("[a-z|A-Z|0-9|._-]*"))
|
||||||
{
|
{
|
||||||
|
QTC_CHECK(m_sdkManager);
|
||||||
m_avdDialog.setupUi(this);
|
m_avdDialog.setupUi(this);
|
||||||
m_hideTipTimer.setInterval(2000);
|
m_hideTipTimer.setInterval(2000);
|
||||||
m_hideTipTimer.setSingleShot(true);
|
m_hideTipTimer.setSingleShot(true);
|
||||||
@@ -70,12 +75,27 @@ AvdDialog::AvdDialog(int minApiLevel, const QString &targetArch, const AndroidCo
|
|||||||
|
|
||||||
bool AvdDialog::isValid() const
|
bool AvdDialog::isValid() const
|
||||||
{
|
{
|
||||||
return !name().isEmpty() && target().isValid() && !abi().isEmpty();
|
return !name().isEmpty() && sdkPlatform() && sdkPlatform()->isValid() && !abi().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
SdkPlatform AvdDialog::target() const
|
CreateAvdInfo AvdDialog::gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
|
||||||
|
int minApiLevel, QString targetArch)
|
||||||
{
|
{
|
||||||
return m_avdDialog.targetComboBox->currentData().value<SdkPlatform>();
|
CreateAvdInfo result;
|
||||||
|
AvdDialog d(minApiLevel, sdkManager, targetArch, parent);
|
||||||
|
if (d.exec() != QDialog::Accepted || !d.isValid())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result.sdkPlatform = d.sdkPlatform();
|
||||||
|
result.name = d.name();
|
||||||
|
result.abi = d.abi();
|
||||||
|
result.sdcardSize = d.sdcardSize();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SdkPlatform* AvdDialog::sdkPlatform() const
|
||||||
|
{
|
||||||
|
return m_avdDialog.targetComboBox->currentData().value<SdkPlatform*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AvdDialog::name() const
|
QString AvdDialog::name() const
|
||||||
@@ -96,21 +116,23 @@ int AvdDialog::sdcardSize() const
|
|||||||
void AvdDialog::updateApiLevelComboBox()
|
void AvdDialog::updateApiLevelComboBox()
|
||||||
{
|
{
|
||||||
SdkPlatformList filteredList;
|
SdkPlatformList filteredList;
|
||||||
SdkPlatformList platforms = m_config->sdkTargets(m_minApiLevel);
|
const SdkPlatformList platforms = m_sdkManager->filteredSdkPlatforms(m_minApiLevel);
|
||||||
|
|
||||||
QString selectedAbi = abi();
|
QString selectedAbi = abi();
|
||||||
auto hasAbi = [selectedAbi](const SystemImage &image) {
|
auto hasAbi = [selectedAbi](const SystemImage *image) {
|
||||||
return image.isValid() && (image.abiName == selectedAbi);
|
return image && image->isValid() && (image->abiName() == selectedAbi);
|
||||||
};
|
};
|
||||||
|
|
||||||
filteredList = Utils::filtered(platforms, [hasAbi](const SdkPlatform &platform) {
|
filteredList = Utils::filtered(platforms, [hasAbi](const SdkPlatform *platform) {
|
||||||
return Utils::anyOf(platform.systemImages,hasAbi);
|
return platform && Utils::anyOf(platform->systemImages(), hasAbi);
|
||||||
});
|
});
|
||||||
|
|
||||||
m_avdDialog.targetComboBox->clear();
|
m_avdDialog.targetComboBox->clear();
|
||||||
foreach (const SdkPlatform &platform, filteredList) {
|
for (SdkPlatform *platform: filteredList) {
|
||||||
m_avdDialog.targetComboBox->addItem(AndroidConfig::apiLevelNameFor(platform),
|
m_avdDialog.targetComboBox->addItem(platform->displayText(),
|
||||||
QVariant::fromValue<SdkPlatform>(platform));
|
QVariant::fromValue<SdkPlatform *>(platform));
|
||||||
|
m_avdDialog.targetComboBox->setItemData(m_avdDialog.targetComboBox->count() - 1,
|
||||||
|
platform->descriptionText(), Qt::ToolTipRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platforms.isEmpty()) {
|
if (platforms.isEmpty()) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "androidconfigurations.h"
|
||||||
#include "ui_addnewavddialog.h"
|
#include "ui_addnewavddialog.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
@@ -35,26 +35,28 @@ class AndroidConfig;
|
|||||||
class SdkPlatform;
|
class SdkPlatform;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class AndroidSdkManager;
|
||||||
class AvdDialog : public QDialog
|
class AvdDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AvdDialog(int minApiLevel, const QString &targetArch,
|
explicit AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QString &targetArch,
|
||||||
const AndroidConfig *config, QWidget *parent = 0);
|
QWidget *parent = 0);
|
||||||
|
|
||||||
Android::SdkPlatform target() const;
|
const SdkPlatform *sdkPlatform() const;
|
||||||
QString name() const;
|
QString name() const;
|
||||||
QString abi() const;
|
QString abi() const;
|
||||||
int sdcardSize() const;
|
int sdcardSize() const;
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
static CreateAvdInfo gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
|
||||||
|
int minApiLevel = 0, QString targetArch = QString());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateApiLevelComboBox();
|
void updateApiLevelComboBox();
|
||||||
bool eventFilter(QObject *obj, QEvent *event);
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
|
||||||
Ui::AddNewAVDDialog m_avdDialog;
|
Ui::AddNewAVDDialog m_avdDialog;
|
||||||
const AndroidConfig *m_config;
|
AndroidSdkManager *m_sdkManager;
|
||||||
int m_minApiLevel;
|
int m_minApiLevel;
|
||||||
QTimer m_hideTipTimer;
|
QTimer m_hideTipTimer;
|
||||||
QRegExp m_allowedNameChars;
|
QRegExp m_allowedNameChars;
|
||||||
|
|||||||
Reference in New Issue
Block a user