forked from qt-creator/qt-creator
Android: Improve "Add new AVD" dialog
* Re-organize the implementation to create a new AVD * Use SystemImage instead of SdKPlatform because now an SdkPlatform can be installed partially with a SystemImage. The current implementation does not consider the this case, thus we end up with an uncomplete list of installed system images. * Add Device definitions with categories (phone, tablet, tv, etc.) to the creation process (check -d arg in avdmanager create avd). Task-number: QTCREATORBUG-23284 Change-Id: Id02a71ad452fb423fa2781d06ef3fcf2afa328a9 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>187</height>
|
||||
<height>243</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
@@ -30,45 +30,49 @@
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="nameLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="abiLabel">
|
||||
<property name="text">
|
||||
<string>Architecture (ABI):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="abiComboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="targetApiLabel">
|
||||
<property name="text">
|
||||
<string>Target API:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="targetApiComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Utils::InfoLabel" name="warningText"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="sdcardSizeLabel">
|
||||
<property name="text">
|
||||
<string>SD card size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="targetApiLabel">
|
||||
<property name="text">
|
||||
<string>Target API:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="deviceDefinitionLabel">
|
||||
<property name="text">
|
||||
<string>Device definition:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="abiComboBox"/>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="sdcardSizeSpinBox">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@@ -87,6 +91,35 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="nameLineEdit"/>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="targetApiComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="deviceDefinitionComboBox"/>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="Utils::InfoLabel" name="warningText"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="deviceDefinitionTypeComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="overwriteCheckBox">
|
||||
<property name="text">
|
||||
<string>Overwrite existing AVD name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -71,7 +71,7 @@ const int avdCreateTimeoutMs = 30000;
|
||||
\c true if the command is successfully executed. Output is copied into \a output. The function
|
||||
blocks the calling thread.
|
||||
*/
|
||||
static bool avdManagerCommand(const AndroidConfig config, const QStringList &args, QString *output)
|
||||
bool AndroidAvdManager::avdManagerCommand(const AndroidConfig config, const QStringList &args, QString *output)
|
||||
{
|
||||
CommandLine cmd(config.avdManagerToolPath(), args);
|
||||
Utils::SynchronousProcess proc;
|
||||
@@ -118,7 +118,7 @@ static CreateAvdInfo createAvdCommand(const AndroidConfig config, const CreateAv
|
||||
|
||||
if (!result.isValid()) {
|
||||
qCDebug(avdManagerLog) << "AVD Create failed. Invalid CreateAvdInfo" << result.name
|
||||
<< result.sdkPlatform->displayText() << result.sdkPlatform->apiLevel();
|
||||
<< result.systemImage->displayText() << result.systemImage->apiLevel();
|
||||
result.error = QApplication::translate("AndroidAvdManager",
|
||||
"Cannot create AVD. Invalid input.");
|
||||
return result;
|
||||
@@ -126,28 +126,17 @@ static CreateAvdInfo createAvdCommand(const AndroidConfig config, const CreateAv
|
||||
|
||||
QStringList arguments({"create", "avd", "-n", result.name});
|
||||
|
||||
if (!result.abi.isEmpty()) {
|
||||
SystemImage *image = Utils::findOrDefault(result.sdkPlatform->systemImages(),
|
||||
Utils::equal(&SystemImage::abiName, result.abi));
|
||||
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 << name;
|
||||
result.error = QApplication::translate("AndroidAvdManager",
|
||||
"Cannot create AVD. Cannot find system image for "
|
||||
"the ABI %1(%2).").arg(result.abi).arg(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
} else {
|
||||
arguments << "-k" << result.sdkPlatform->sdkStylePath();
|
||||
}
|
||||
arguments << "-k" << result.systemImage->sdkStylePath();
|
||||
|
||||
if (result.sdcardSize > 0)
|
||||
arguments << "-c" << QString::fromLatin1("%1M").arg(result.sdcardSize);
|
||||
|
||||
if (!result.deviceDefinition.isEmpty() && result.deviceDefinition != "Custom")
|
||||
arguments << "-d" << QString::fromLatin1("%1").arg(result.deviceDefinition);
|
||||
|
||||
if (result.overwrite)
|
||||
arguments << "-f";
|
||||
|
||||
QProcess proc;
|
||||
proc.start(config.avdManagerToolPath().toString(), arguments);
|
||||
if (!proc.waitForStarted()) {
|
||||
@@ -419,7 +408,7 @@ AndroidDeviceInfoList AvdManagerOutputParser::listVirtualDevices(const AndroidCo
|
||||
AndroidDeviceInfoList avdList;
|
||||
|
||||
do {
|
||||
if (!avdManagerCommand(config, {"list", "avd"}, &output)) {
|
||||
if (!AndroidAvdManager::avdManagerCommand(config, {"list", "avd"}, &output)) {
|
||||
qCDebug(avdManagerLog)
|
||||
<< "Avd list command failed" << output << config.sdkToolsVersion();
|
||||
return {};
|
||||
|
||||
@@ -54,6 +54,9 @@ public:
|
||||
QString waitForAvd(const QString &avdName,
|
||||
const std::function<bool()> &cancelChecker = {}) const;
|
||||
bool isAvdBooted(const QString &device) const;
|
||||
static bool avdManagerCommand(const AndroidConfig config,
|
||||
const QStringList &args,
|
||||
QString *output);
|
||||
|
||||
private:
|
||||
bool waitForBooted(const QString &serialNumber,
|
||||
|
||||
@@ -85,12 +85,14 @@ using AndroidDeviceInfoList = QList<AndroidDeviceInfo>;
|
||||
class CreateAvdInfo
|
||||
{
|
||||
public:
|
||||
bool isValid() const { return sdkPlatform && sdkPlatform->isValid() && !name.isEmpty(); }
|
||||
const SdkPlatform *sdkPlatform = nullptr;
|
||||
bool isValid() const { return systemImage && systemImage->isValid() && !name.isEmpty(); }
|
||||
const SystemImage *systemImage = nullptr;
|
||||
QString name;
|
||||
QString abi;
|
||||
QString deviceDefinition;
|
||||
int sdcardSize = 0;
|
||||
QString error; // only used in the return value of createAVD
|
||||
bool overwrite = false;
|
||||
};
|
||||
|
||||
class ANDROID_EXPORT AndroidConfig
|
||||
|
||||
@@ -578,7 +578,7 @@ void AndroidDeviceDialog::createAvd()
|
||||
{
|
||||
m_ui->createAVDButton->setEnabled(false);
|
||||
CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, AndroidConfigurations::sdkManager(),
|
||||
m_apiLevel, m_abis);
|
||||
AndroidConfigurations::currentConfig(), m_apiLevel, m_abis);
|
||||
|
||||
if (!info.isValid()) {
|
||||
m_ui->createAVDButton->setEnabled(true);
|
||||
|
||||
@@ -345,6 +345,21 @@ AndroidSdkPackageList AndroidSdkManager::installedSdkPackages()
|
||||
return m_d->filteredPackages(AndroidSdkPackage::Installed, AndroidSdkPackage::AnyValidType);
|
||||
}
|
||||
|
||||
SystemImageList AndroidSdkManager::installedSystemImages()
|
||||
{
|
||||
AndroidSdkPackageList list = m_d->filteredPackages(AndroidSdkPackage::AnyValidState,
|
||||
AndroidSdkPackage::SdkPlatformPackage);
|
||||
QList<SdkPlatform *> platforms = Utils::static_container_cast<SdkPlatform *>(list);
|
||||
|
||||
SystemImageList result;
|
||||
for (SdkPlatform *platform : platforms) {
|
||||
if (platform->systemImages().size() > 0)
|
||||
result.append(platform->systemImages());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SdkPlatform *AndroidSdkManager::latestAndroidSdkPlatform(AndroidSdkPackage::PackageState state)
|
||||
{
|
||||
SdkPlatform *result = nullptr;
|
||||
@@ -679,6 +694,7 @@ QPair<SystemImage *, int> SdkManagerOutputParser::parseSystemImage(const QString
|
||||
image->setInstalledLocation(packageData.installedLocation);
|
||||
image->setDisplayText(packageData.description);
|
||||
image->setDescriptionText(packageData.description);
|
||||
image->setApiLevel(apiLevel);
|
||||
result = qMakePair(image, apiLevel);
|
||||
} else {
|
||||
qCDebug(sdkManagerLog) << "System-image: Minimum required data unavailable: "<< data;
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
const AndroidSdkPackageList &allSdkPackages();
|
||||
AndroidSdkPackageList availableSdkPackages();
|
||||
AndroidSdkPackageList installedSdkPackages();
|
||||
SystemImageList installedSystemImages();
|
||||
|
||||
SdkPlatform *latestAndroidSdkPlatform(AndroidSdkPackage::PackageState state
|
||||
= AndroidSdkPackage::Installed);
|
||||
|
||||
@@ -134,6 +134,16 @@ void SystemImage::setPlatform(SdkPlatform *platform)
|
||||
m_platform = platform;
|
||||
}
|
||||
|
||||
int SystemImage::apiLevel() const
|
||||
{
|
||||
return m_apiLevel;
|
||||
}
|
||||
|
||||
void SystemImage::setApiLevel(const int apiLevel)
|
||||
{
|
||||
m_apiLevel = apiLevel;
|
||||
}
|
||||
|
||||
SdkPlatform::SdkPlatform(QVersionNumber version, QString sdkStylePathStr, int api, QObject *parent) :
|
||||
AndroidSdkPackage(version, sdkStylePathStr, parent),
|
||||
m_apiLevel(api)
|
||||
|
||||
@@ -114,10 +114,13 @@ public:
|
||||
const QString &abiName() const;
|
||||
const SdkPlatform *platform() const;
|
||||
void setPlatform(SdkPlatform *platform);
|
||||
int apiLevel() const;
|
||||
void setApiLevel(const int apiLevel);
|
||||
|
||||
private:
|
||||
QPointer<SdkPlatform> m_platform;
|
||||
QString m_abiName;
|
||||
int m_apiLevel = -1;
|
||||
};
|
||||
using SystemImageList = QList<SystemImage*>;
|
||||
|
||||
|
||||
@@ -260,7 +260,8 @@ QVariant AvdModel::data(const QModelIndex &index, int role) const
|
||||
return cpuAbis.isEmpty() ? QVariant() : QVariant(cpuAbis.first());
|
||||
}
|
||||
case 3:
|
||||
return currentRow.avdDevice;
|
||||
return currentRow.avdDevice.isEmpty() ? QVariant("Custom")
|
||||
: currentRow.avdDevice;
|
||||
case 4:
|
||||
return currentRow.avdTarget;
|
||||
case 5:
|
||||
@@ -556,7 +557,7 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl()
|
||||
void AndroidSettingsWidget::addAVD()
|
||||
{
|
||||
disableAvdControls();
|
||||
CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, m_sdkManager.get());
|
||||
CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, m_sdkManager.get(), m_androidConfig);
|
||||
|
||||
if (!info.isValid()) {
|
||||
enableAvdControls();
|
||||
|
||||
@@ -148,7 +148,7 @@ CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FilePath and
|
||||
proc.setProcessEnvironment(env);
|
||||
QStringList arguments;
|
||||
arguments << QLatin1String("create") << QLatin1String("avd")
|
||||
<< QLatin1String("-t") << AndroidConfig::apiLevelNameFor(info.sdkPlatform)
|
||||
<< QLatin1String("-t") << QString("android-%1").arg(info.systemImage->apiLevel())
|
||||
<< QLatin1String("-n") << info.name
|
||||
<< QLatin1String("-b") << info.abi;
|
||||
if (info.sdcardSize > 0)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "avddialog.h"
|
||||
#include "androidsdkmanager.h"
|
||||
#include "androidavdmanager.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
@@ -34,16 +35,22 @@
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QToolTip>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
using namespace Android;
|
||||
using namespace Android::Internal;
|
||||
|
||||
namespace {
|
||||
Q_LOGGING_CATEGORY(avdDialogLog, "qtc.android.avdDialog", QtWarningMsg)
|
||||
}
|
||||
|
||||
AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStringList &abis,
|
||||
QWidget *parent) :
|
||||
const AndroidConfig &config, 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|._-]*")),
|
||||
m_androidConfig(config)
|
||||
{
|
||||
QTC_CHECK(m_sdkManager);
|
||||
m_avdDialog.setupUi(this);
|
||||
@@ -63,39 +70,119 @@ AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStri
|
||||
|
||||
m_avdDialog.warningText->setType(Utils::InfoLabel::Warning);
|
||||
|
||||
updateApiLevelComboBox();
|
||||
connect(&m_hideTipTimer, &QTimer::timeout, this, []() { Utils::ToolTip::hide(); });
|
||||
|
||||
parseDeviceDefinitionsList();
|
||||
for (const QString &type : DeviceTypeToStringMap.values())
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->addItem(type);
|
||||
|
||||
connect(m_avdDialog.deviceDefinitionTypeComboBox,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&AvdDialog::updateDeviceDefinitionComboBox);
|
||||
connect(m_avdDialog.abiComboBox,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &AvdDialog::updateApiLevelComboBox);
|
||||
|
||||
connect(&m_hideTipTimer, &QTimer::timeout,
|
||||
this, [](){Utils::ToolTip::hide();});
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->setCurrentIndex(1); // Set Phone type as default index
|
||||
updateApiLevelComboBox();
|
||||
}
|
||||
|
||||
bool AvdDialog::isValid() const
|
||||
{
|
||||
return !name().isEmpty() && sdkPlatform() && sdkPlatform()->isValid() && !abi().isEmpty();
|
||||
return !name().isEmpty() && systemImage() && systemImage()->isValid() && !abi().isEmpty();
|
||||
}
|
||||
|
||||
CreateAvdInfo AvdDialog::gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
|
||||
int minApiLevel, const QStringList &abis)
|
||||
const AndroidConfig &config, int minApiLevel, const QStringList &abis)
|
||||
{
|
||||
CreateAvdInfo result;
|
||||
AvdDialog d(minApiLevel, sdkManager, abis, parent);
|
||||
AvdDialog d(minApiLevel, sdkManager, abis, config, parent);
|
||||
if (d.exec() != QDialog::Accepted || !d.isValid())
|
||||
return result;
|
||||
|
||||
result.sdkPlatform = d.sdkPlatform();
|
||||
result.systemImage = d.systemImage();
|
||||
result.name = d.name();
|
||||
result.abi = d.abi();
|
||||
result.deviceDefinition = d.deviceDefinition();
|
||||
result.sdcardSize = d.sdcardSize();
|
||||
result.overwrite = d.m_avdDialog.overwriteCheckBox->isChecked();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const SdkPlatform* AvdDialog::sdkPlatform() const
|
||||
AvdDialog::DeviceType AvdDialog::tagToDeviceType(const QString &type_tag)
|
||||
{
|
||||
return m_avdDialog.targetApiComboBox->currentData().value<SdkPlatform*>();
|
||||
if (type_tag.contains("android-wear"))
|
||||
return AvdDialog::Wear;
|
||||
else if (type_tag.contains("android-tv"))
|
||||
return AvdDialog::TV;
|
||||
else if (type_tag.contains("android-automotive"))
|
||||
return AvdDialog::Automotive;
|
||||
else
|
||||
return AvdDialog::PhoneOrTablet;
|
||||
}
|
||||
|
||||
void AvdDialog::parseDeviceDefinitionsList()
|
||||
{
|
||||
QString output;
|
||||
|
||||
if (!AndroidAvdManager::avdManagerCommand(m_androidConfig, {"list", "device"}, &output)) {
|
||||
qCDebug(avdDialogLog) << "Avd list command failed" << output
|
||||
<< m_androidConfig.sdkToolsVersion();
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList avdDeviceInfo;
|
||||
|
||||
for (QString line : output.split('\n')) {
|
||||
if (line.startsWith("---------") || line.isEmpty()) {
|
||||
DeviceDefinitionStruct deviceDefinition;
|
||||
for (const QString &line : avdDeviceInfo) {
|
||||
QString value;
|
||||
if (line.contains("id:")) {
|
||||
deviceDefinition.name_id = line.split("or").at(1);
|
||||
deviceDefinition.name_id = deviceDefinition.name_id.remove(0, 1).remove('"');
|
||||
} else if (line.contains("Tag :")) {
|
||||
deviceDefinition.type_str = line.split(':').at(1);
|
||||
deviceDefinition.type_str = deviceDefinition.type_str.remove(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceType deviceType = tagToDeviceType(deviceDefinition.type_str);
|
||||
if (deviceType == PhoneOrTablet) {
|
||||
if (deviceDefinition.name_id.contains("Tablet"))
|
||||
deviceType = Tablet;
|
||||
else
|
||||
deviceType = Phone;
|
||||
}
|
||||
deviceDefinition.deviceType = deviceType;
|
||||
m_deviceDefinitionsList.append(deviceDefinition);
|
||||
avdDeviceInfo.clear();
|
||||
} else {
|
||||
avdDeviceInfo << line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AvdDialog::updateDeviceDefinitionComboBox()
|
||||
{
|
||||
DeviceType curDeviceType = DeviceTypeToStringMap.key(
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->currentText());
|
||||
|
||||
m_avdDialog.deviceDefinitionComboBox->clear();
|
||||
for (auto item : m_deviceDefinitionsList) {
|
||||
if (item.deviceType == curDeviceType)
|
||||
m_avdDialog.deviceDefinitionComboBox->addItem(item.name_id);
|
||||
}
|
||||
m_avdDialog.deviceDefinitionComboBox->addItem("Custom");
|
||||
|
||||
updateApiLevelComboBox();
|
||||
}
|
||||
|
||||
const SystemImage* AvdDialog::systemImage() const
|
||||
{
|
||||
return m_avdDialog.targetApiComboBox->currentData().value<SystemImage*>();
|
||||
}
|
||||
|
||||
QString AvdDialog::name() const
|
||||
@@ -108,6 +195,11 @@ QString AvdDialog::abi() const
|
||||
return m_avdDialog.abiComboBox->currentText();
|
||||
}
|
||||
|
||||
QString AvdDialog::deviceDefinition() const
|
||||
{
|
||||
return m_avdDialog.deviceDefinitionComboBox->currentText();
|
||||
}
|
||||
|
||||
int AvdDialog::sdcardSize() const
|
||||
{
|
||||
return m_avdDialog.sdcardSizeSpinBox->value();
|
||||
@@ -115,37 +207,49 @@ int AvdDialog::sdcardSize() const
|
||||
|
||||
void AvdDialog::updateApiLevelComboBox()
|
||||
{
|
||||
SdkPlatformList filteredList;
|
||||
const SdkPlatformList platforms = m_sdkManager->filteredSdkPlatforms(m_minApiLevel);
|
||||
SystemImageList installedSystemImages = m_sdkManager->installedSystemImages();
|
||||
DeviceType curDeviceType = DeviceTypeToStringMap.key(
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->currentText());
|
||||
|
||||
QString selectedAbi = abi();
|
||||
auto hasAbi = [selectedAbi](const SystemImage *image) {
|
||||
return image && image->isValid() && (image->abiName() == selectedAbi);
|
||||
};
|
||||
|
||||
filteredList = Utils::filtered(platforms, [hasAbi](const SdkPlatform *platform) {
|
||||
return platform && Utils::anyOf(platform->systemImages(), hasAbi);
|
||||
SystemImageList filteredList;
|
||||
filteredList = Utils::filtered(installedSystemImages, [hasAbi, &curDeviceType](const SystemImage *image) {
|
||||
DeviceType deviceType = tagToDeviceType(image->sdkStylePath().split(';').at(2));
|
||||
if (deviceType == PhoneOrTablet && (curDeviceType == Phone || curDeviceType == Tablet))
|
||||
curDeviceType = PhoneOrTablet;
|
||||
return image && deviceType == curDeviceType && hasAbi(image);
|
||||
});
|
||||
|
||||
m_avdDialog.targetApiComboBox->clear();
|
||||
for (SdkPlatform *platform: filteredList) {
|
||||
m_avdDialog.targetApiComboBox->addItem(platform->displayText(),
|
||||
QVariant::fromValue<SdkPlatform *>(platform));
|
||||
for (SystemImage *image : filteredList) {
|
||||
QString imageString = "android-" % QString::number(image->apiLevel());
|
||||
if (image->sdkStylePath().contains("playstore"))
|
||||
imageString += " (Google PlayStore)";
|
||||
m_avdDialog.targetApiComboBox->addItem(imageString,
|
||||
QVariant::fromValue<SystemImage *>(image));
|
||||
m_avdDialog.targetApiComboBox->setItemData(m_avdDialog.targetApiComboBox->count() - 1,
|
||||
platform->descriptionText(), Qt::ToolTipRole);
|
||||
image->descriptionText(),
|
||||
Qt::ToolTipRole);
|
||||
}
|
||||
|
||||
if (platforms.isEmpty()) {
|
||||
if (installedSystemImages.isEmpty()) {
|
||||
m_avdDialog.targetApiComboBox->setEnabled(false);
|
||||
m_avdDialog.warningText->setVisible(true);
|
||||
m_avdDialog.warningText->setText(tr("Cannot create a new AVD. No sufficiently recent Android SDK available.\n"
|
||||
"Install an SDK of at least API version %1.")
|
||||
.arg(m_minApiLevel));
|
||||
} else if (filteredList.isEmpty()) {
|
||||
m_avdDialog.targetApiComboBox->setEnabled(false);
|
||||
m_avdDialog.warningText->setVisible(true);
|
||||
m_avdDialog.warningText->setText(tr("Cannot create a AVD for ABI %1. Install an image for it.")
|
||||
.arg(abi()));
|
||||
} else {
|
||||
m_avdDialog.warningText->setVisible(false);
|
||||
m_avdDialog.targetApiComboBox->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
#include "androidconfigurations.h"
|
||||
#include "ui_addnewavddialog.h"
|
||||
#include "androidconfigurations.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTimer>
|
||||
@@ -40,18 +41,43 @@ class AvdDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStringList &abis,
|
||||
explicit AvdDialog(int minApiLevel,
|
||||
AndroidSdkManager *sdkManager,
|
||||
const QStringList &abis,
|
||||
const AndroidConfig &config,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
const SdkPlatform *sdkPlatform() const;
|
||||
enum DeviceType { TV, Phone, Wear, Tablet, Automotive, PhoneOrTablet };
|
||||
|
||||
const QMap<DeviceType, QString> DeviceTypeToStringMap{
|
||||
{TV, "TV"},
|
||||
{Phone, "Phone"},
|
||||
{Wear, "Wear"},
|
||||
{Tablet, "Tablet"},
|
||||
{Automotive, "Automotive"}
|
||||
};
|
||||
|
||||
struct DeviceDefinitionStruct
|
||||
{
|
||||
QString name_id;
|
||||
QString type_str;
|
||||
DeviceType deviceType;
|
||||
};
|
||||
|
||||
const SystemImage *systemImage() const;
|
||||
QString name() const;
|
||||
QString abi() const;
|
||||
QString deviceDefinition() const;
|
||||
int sdcardSize() const;
|
||||
bool isValid() const;
|
||||
static AvdDialog::DeviceType tagToDeviceType(const QString &type_tag);
|
||||
static CreateAvdInfo gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
|
||||
const AndroidConfig &config,
|
||||
int minApiLevel = 0, const QStringList &abis = {});
|
||||
|
||||
private:
|
||||
void parseDeviceDefinitionsList();
|
||||
void updateDeviceDefinitionComboBox();
|
||||
void updateApiLevelComboBox();
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
@@ -60,6 +86,8 @@ private:
|
||||
int m_minApiLevel;
|
||||
QTimer m_hideTipTimer;
|
||||
QRegExp m_allowedNameChars;
|
||||
QList<DeviceDefinitionStruct> m_deviceDefinitionsList;
|
||||
AndroidConfig m_androidConfig;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user