forked from qt-creator/qt-creator
Android: Do some refactoring for AvdDialog class
Move some logic for avd creation to the AvdDialog, and some refactoring and simplification. Change-Id: Id65e586ab1c0e9e898a04f07d7707371f20da649 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -604,50 +604,20 @@ AndroidDeviceFactory::AndroidDeviceFactory()
|
||||
|
||||
IDevice::Ptr AndroidDeviceFactory::create() const
|
||||
{
|
||||
AndroidSdkManager sdkManager = AndroidSdkManager(m_androidConfig);
|
||||
const CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(Core::ICore::dialogParent(),
|
||||
&sdkManager, m_androidConfig);
|
||||
if (!info.isValid()) {
|
||||
if (!info.cancelled) {
|
||||
AndroidDeviceWidget::criticalDialog(
|
||||
QObject::tr("The returned device info is invalid."));
|
||||
}
|
||||
return nullptr;
|
||||
AvdDialog dialog = AvdDialog(m_androidConfig, Core::ICore::dialogParent());
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
return ProjectExplorer::IDevice::Ptr();
|
||||
|
||||
const ProjectExplorer::IDevice::Ptr dev = dialog.device();
|
||||
const AndroidDevice *androidDev = static_cast<AndroidDevice*>(dev.data());
|
||||
if (androidDev) {
|
||||
qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".",
|
||||
qPrintable(androidDev->avdName()));
|
||||
} else {
|
||||
AndroidDeviceWidget::criticalDialog(
|
||||
QObject::tr("The device info returned from AvdDialog is invalid."));
|
||||
}
|
||||
|
||||
const AndroidAvdManager avdManager = AndroidAvdManager(m_androidConfig);
|
||||
QFutureWatcher<CreateAvdInfo> createAvdFutureWatcher;
|
||||
createAvdFutureWatcher.setFuture(avdManager.createAvd(info));
|
||||
|
||||
QEventLoop loop;
|
||||
QObject::connect(&createAvdFutureWatcher, &QFutureWatcher<CreateAvdInfo>::finished,
|
||||
&loop, &QEventLoop::quit);
|
||||
QObject::connect(&createAvdFutureWatcher, &QFutureWatcher<CreateAvdInfo>::canceled,
|
||||
&loop, &QEventLoop::quit);
|
||||
loop.exec(QEventLoop::ExcludeUserInputEvents);
|
||||
|
||||
QFuture<CreateAvdInfo> future = createAvdFutureWatcher.future();
|
||||
if (!(future.isResultReadyAt(0) && future.result().isValid())) {
|
||||
AndroidDeviceWidget::criticalDialog(QObject::tr("The device info returned by "
|
||||
"avdmanager tool is invalid for the device name \"%1\".").arg(info.name));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CreateAvdInfo newAvdInfo = createAvdFutureWatcher.result();
|
||||
|
||||
AndroidDevice *dev = new AndroidDevice();
|
||||
const Utils::Id deviceId = AndroidDevice::idFromAvdInfo(newAvdInfo);
|
||||
dev->setupId(IDevice::AutoDetected, deviceId);
|
||||
dev->setMachineType(IDevice::Emulator);
|
||||
dev->setDisplayName(newAvdInfo.name);
|
||||
dev->setDeviceState(IDevice::DeviceConnected);
|
||||
dev->setExtraData(Constants::AndroidAvdName, newAvdInfo.name);
|
||||
dev->setExtraData(Constants::AndroidCpuAbi, {newAvdInfo.abi});
|
||||
dev->setExtraData(Constants::AndroidSdk, newAvdInfo.systemImage->apiLevel());
|
||||
dev->setExtraData(Constants::AndroidAvdSdcard, QString("%1 MB").arg(newAvdInfo.sdcardSize));
|
||||
dev->setExtraData(Constants::AndroidAvdDevice, newAvdInfo.deviceDefinition);
|
||||
|
||||
qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".", qPrintable(newAvdInfo.name));
|
||||
return IDevice::Ptr(dev);
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include "avddialog.h"
|
||||
#include "androidsdkmanager.h"
|
||||
#include "androidavdmanager.h"
|
||||
#include "androiddevice.h"
|
||||
#include "androidconstants.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <utils/algorithm.h>
|
||||
@@ -33,6 +35,7 @@
|
||||
#include <utils/utilsicons.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QToolTip>
|
||||
@@ -46,29 +49,35 @@ namespace {
|
||||
static Q_LOGGING_CATEGORY(avdDialogLog, "qtc.android.avdDialog", QtWarningMsg)
|
||||
}
|
||||
|
||||
AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStringList &abis,
|
||||
const AndroidConfig &config, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_sdkManager(sdkManager),
|
||||
m_minApiLevel(minApiLevel),
|
||||
m_allowedNameChars(QLatin1String("[a-z|A-Z|0-9|._-]*")),
|
||||
m_androidConfig(config)
|
||||
AvdDialog::AvdDialog(const AndroidConfig &config, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
m_sdkManager(m_androidConfig),
|
||||
m_allowedNameChars(QLatin1String("[a-z|A-Z|0-9|._-]*")),
|
||||
m_androidConfig(config)
|
||||
{
|
||||
QTC_CHECK(m_sdkManager);
|
||||
m_avdDialog.setupUi(this);
|
||||
m_hideTipTimer.setInterval(2000);
|
||||
m_hideTipTimer.setSingleShot(true);
|
||||
|
||||
if (abis.isEmpty()) {
|
||||
m_avdDialog.abiComboBox->addItems(QStringList({
|
||||
ProjectExplorer::Constants::ANDROID_ABI_X86,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_X86_64,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_ARMEABI_V7A,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_ARMEABI,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A}));
|
||||
} else {
|
||||
m_avdDialog.abiComboBox->addItems(abis);
|
||||
}
|
||||
connect(&m_hideTipTimer, &QTimer::timeout, this, &Utils::ToolTip::hide);
|
||||
connect(m_avdDialog.deviceDefinitionTypeComboBox,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &AvdDialog::updateDeviceDefinitionComboBox);
|
||||
connect(m_avdDialog.abiComboBox,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &AvdDialog::updateApiLevelComboBox);
|
||||
|
||||
deviceTypeToStringMap.insert(AvdDialog::Phone, "Phone");
|
||||
deviceTypeToStringMap.insert(AvdDialog::Tablet, "Tablet");
|
||||
deviceTypeToStringMap.insert(AvdDialog::Automotive, "Automotive");
|
||||
deviceTypeToStringMap.insert(AvdDialog::TV, "TV");
|
||||
deviceTypeToStringMap.insert(AvdDialog::Wear, "Wear");
|
||||
|
||||
m_avdDialog.abiComboBox->addItems(QStringList({
|
||||
ProjectExplorer::Constants::ANDROID_ABI_X86,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_X86_64,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_ARMEABI_V7A,
|
||||
ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A}));
|
||||
|
||||
auto v = new QRegularExpressionValidator(m_allowedNameChars, this);
|
||||
m_avdDialog.nameLineEdit->setValidator(v);
|
||||
@@ -77,46 +86,70 @@ AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStri
|
||||
m_avdDialog.warningText->setType(Utils::InfoLabel::Warning);
|
||||
m_avdDialog.warningText->setElideMode(Qt::ElideNone);
|
||||
|
||||
connect(&m_hideTipTimer, &QTimer::timeout, this, []() { Utils::ToolTip::hide(); });
|
||||
|
||||
parseDeviceDefinitionsList();
|
||||
for (const QString &type : DeviceTypeToStringMap)
|
||||
for (const QString &type : deviceTypeToStringMap)
|
||||
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);
|
||||
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->setCurrentIndex(1); // Set Phone type as default index
|
||||
updateApiLevelComboBox();
|
||||
}
|
||||
|
||||
int AvdDialog::exec()
|
||||
{
|
||||
const int execResult = QDialog::exec();
|
||||
if (execResult == QDialog::Accepted) {
|
||||
CreateAvdInfo result;
|
||||
result.systemImage = systemImage();
|
||||
result.name = name();
|
||||
result.abi = abi();
|
||||
result.deviceDefinition = deviceDefinition();
|
||||
result.sdcardSize = sdcardSize();
|
||||
result.overwrite = m_avdDialog.overwriteCheckBox->isChecked();
|
||||
|
||||
const AndroidAvdManager avdManager = AndroidAvdManager(m_androidConfig);
|
||||
QFutureWatcher<CreateAvdInfo> createAvdFutureWatcher;
|
||||
createAvdFutureWatcher.setFuture(avdManager.createAvd(result));
|
||||
|
||||
QEventLoop loop;
|
||||
QObject::connect(&createAvdFutureWatcher, &QFutureWatcher<CreateAvdInfo>::finished,
|
||||
&loop, &QEventLoop::quit);
|
||||
QObject::connect(&createAvdFutureWatcher, &QFutureWatcher<CreateAvdInfo>::canceled,
|
||||
&loop, &QEventLoop::quit);
|
||||
loop.exec(QEventLoop::ExcludeUserInputEvents);
|
||||
|
||||
const QFuture<CreateAvdInfo> future = createAvdFutureWatcher.future();
|
||||
if (future.isResultReadyAt(0))
|
||||
m_createdAvdInfo = future.result();
|
||||
}
|
||||
|
||||
return execResult;
|
||||
}
|
||||
|
||||
bool AvdDialog::isValid() const
|
||||
{
|
||||
return !name().isEmpty() && systemImage() && systemImage()->isValid() && !abi().isEmpty();
|
||||
}
|
||||
|
||||
CreateAvdInfo AvdDialog::gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
|
||||
const AndroidConfig &config, int minApiLevel, const QStringList &abis)
|
||||
ProjectExplorer::IDevice::Ptr AvdDialog::device() const
|
||||
{
|
||||
CreateAvdInfo result;
|
||||
AvdDialog d(minApiLevel, sdkManager, abis, config, parent);
|
||||
result.cancelled = (d.exec() != QDialog::Accepted);
|
||||
if (result.cancelled || !d.isValid())
|
||||
return result;
|
||||
AndroidDevice *dev = new AndroidDevice();
|
||||
const Utils::Id deviceId = AndroidDevice::idFromAvdInfo(m_createdAvdInfo);
|
||||
using namespace ProjectExplorer;
|
||||
dev->setupId(IDevice::AutoDetected, deviceId);
|
||||
dev->setMachineType(IDevice::Emulator);
|
||||
dev->setDisplayName(m_createdAvdInfo.name);
|
||||
dev->setDeviceState(IDevice::DeviceConnected);
|
||||
dev->setExtraData(Constants::AndroidAvdName, m_createdAvdInfo.name);
|
||||
dev->setExtraData(Constants::AndroidCpuAbi, {m_createdAvdInfo.abi});
|
||||
if (!m_createdAvdInfo.systemImage) {
|
||||
qCWarning(avdDialogLog) << "System image of the created AVD is nullptr";
|
||||
return IDevice::Ptr();
|
||||
}
|
||||
dev->setExtraData(Constants::AndroidSdk, m_createdAvdInfo.systemImage->apiLevel());
|
||||
dev->setExtraData(Constants::AndroidAvdSdcard, QString("%1 MB")
|
||||
.arg(m_createdAvdInfo.sdcardSize));
|
||||
dev->setExtraData(Constants::AndroidAvdDevice, m_createdAvdInfo.deviceDefinition);
|
||||
|
||||
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;
|
||||
return IDevice::Ptr(dev);
|
||||
}
|
||||
|
||||
AvdDialog::DeviceType AvdDialog::tagToDeviceType(const QString &type_tag)
|
||||
@@ -175,7 +208,7 @@ void AvdDialog::parseDeviceDefinitionsList()
|
||||
|
||||
void AvdDialog::updateDeviceDefinitionComboBox()
|
||||
{
|
||||
DeviceType curDeviceType = DeviceTypeToStringMap.key(
|
||||
DeviceType curDeviceType = deviceTypeToStringMap.key(
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->currentText());
|
||||
|
||||
m_avdDialog.deviceDefinitionComboBox->clear();
|
||||
@@ -215,8 +248,8 @@ int AvdDialog::sdcardSize() const
|
||||
|
||||
void AvdDialog::updateApiLevelComboBox()
|
||||
{
|
||||
SystemImageList installedSystemImages = m_sdkManager->installedSystemImages();
|
||||
DeviceType curDeviceType = DeviceTypeToStringMap.key(
|
||||
SystemImageList installedSystemImages = m_sdkManager.installedSystemImages();
|
||||
DeviceType curDeviceType = deviceTypeToStringMap.key(
|
||||
m_avdDialog.deviceDefinitionTypeComboBox->currentText());
|
||||
|
||||
QString selectedAbi = abi();
|
||||
@@ -250,8 +283,7 @@ void AvdDialog::updateApiLevelComboBox()
|
||||
m_avdDialog.warningText->setVisible(true);
|
||||
m_avdDialog.warningText->setText(
|
||||
tr("Cannot create a new AVD. No suitable Android system image is installed.<br/>"
|
||||
"Install a system image of at least API version %1 from the SDK Manager tab.")
|
||||
.arg(m_minApiLevel));
|
||||
"Install a system image for the intended Android version from the SDK Manager."));
|
||||
m_avdDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
} else if (filteredList.isEmpty()) {
|
||||
m_avdDialog.targetApiComboBox->setEnabled(false);
|
||||
|
@@ -41,21 +41,27 @@ class AvdDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AvdDialog(int minApiLevel,
|
||||
AndroidSdkManager *sdkManager,
|
||||
const QStringList &abis,
|
||||
const AndroidConfig &config,
|
||||
QWidget *parent = nullptr);
|
||||
explicit AvdDialog(const AndroidConfig &config, QWidget *parent = nullptr);
|
||||
int exec() override;
|
||||
|
||||
enum DeviceType { TV, Phone, Wear, Tablet, Automotive, PhoneOrTablet };
|
||||
enum DeviceType { Phone, Tablet, Automotive, TV, Wear, PhoneOrTablet };
|
||||
|
||||
const QMap<DeviceType, QString> DeviceTypeToStringMap{
|
||||
{TV, "TV"},
|
||||
{Phone, "Phone"},
|
||||
{Wear, "Wear"},
|
||||
{Tablet, "Tablet"},
|
||||
{Automotive, "Automotive"}
|
||||
};
|
||||
ProjectExplorer::IDevice::Ptr device() const;
|
||||
|
||||
const SystemImage *systemImage() const;
|
||||
QString name() const;
|
||||
QString abi() const;
|
||||
QString deviceDefinition() const;
|
||||
int sdcardSize() const;
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
void parseDeviceDefinitionsList();
|
||||
void updateDeviceDefinitionComboBox();
|
||||
void updateApiLevelComboBox();
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
static AvdDialog::DeviceType tagToDeviceType(const QString &type_tag);
|
||||
|
||||
struct DeviceDefinitionStruct
|
||||
{
|
||||
@@ -64,30 +70,14 @@ public:
|
||||
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;
|
||||
|
||||
Ui::AddNewAVDDialog m_avdDialog;
|
||||
AndroidSdkManager *m_sdkManager;
|
||||
int m_minApiLevel;
|
||||
AndroidSdkManager m_sdkManager;
|
||||
CreateAvdInfo m_createdAvdInfo;
|
||||
QTimer m_hideTipTimer;
|
||||
QRegularExpression m_allowedNameChars;
|
||||
QList<DeviceDefinitionStruct> m_deviceDefinitionsList;
|
||||
AndroidConfig m_androidConfig;
|
||||
QMap<AvdDialog::DeviceType, QString> deviceTypeToStringMap;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user