From bee7cdfd1ecfdc6bf27310e500647d321929f5b6 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 13 May 2024 19:15:13 +0200 Subject: [PATCH] Android: Add AndroidDeviceManager::createAvd() The createAvd() command is going to turn off the avd file system watcher during execution, so this needs to be a part of AndroidDeviceManager. Change-Id: Ic8038be53d2be34136649b6b8a44435a4fc87a9f Reviewed-by: Alessandro Portale --- src/plugins/android/androiddevice.cpp | 44 ++++++++++++++++++++++++ src/plugins/android/androiddevice.h | 1 + src/plugins/android/avddialog.cpp | 49 ++++----------------------- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 0242fdeded9..25ea819a422 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -441,6 +441,50 @@ void AndroidDeviceManager::updateDeviceState(const ProjectExplorer::IDevice::Con devMgr->setDeviceState(id, IDevice::DeviceConnected); } +expected_str AndroidDeviceManager::createAvd(const CreateAvdInfo &info, bool force) +{ + CommandLine cmd(androidConfig().avdManagerToolPath(), {"create", "avd", "-n", info.name}); + cmd.addArgs({"-k", info.sdkStylePath}); + if (info.sdcardSize > 0) + cmd.addArgs({"-c", QString("%1M").arg(info.sdcardSize)}); + + const QString deviceDef = info.deviceDefinition; + if (!deviceDef.isEmpty() && deviceDef != "Custom") + cmd.addArgs({"-d", deviceDef}); + + if (force) + cmd.addArg("-f"); + + Process process; + process.setProcessMode(ProcessMode::Writer); + process.setEnvironment(androidConfig().toolsEnvironment()); + process.setCommand(cmd); + process.setWriteData("yes\n"); // yes to "Do you wish to create a custom hardware profile" + + QByteArray buffer; + QObject::connect(&process, &Process::readyReadStandardOutput, &process, [&process, &buffer] { + // This interaction is needed only if there is no "-d" arg for the avdmanager command. + buffer += process.readAllRawStandardOutput(); + if (buffer.endsWith(QByteArray("]:"))) { + // truncate to last line + const int index = buffer.lastIndexOf('\n'); + if (index != -1) + buffer = buffer.mid(index); + if (buffer.contains("hw.gpu.enabled")) + process.write("yes\n"); + else + process.write("\n"); + buffer.clear(); + } + }); + + using namespace std::chrono_literals; + process.runBlocking(); + if (process.result() != ProcessResult::FinishedWithSuccess) + return Utils::make_unexpected(process.exitMessage()); + return {}; +} + void AndroidDeviceManager::startAvd(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent) { Q_UNUSED(parent) diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h index 57b386dc4d9..739e9c2753f 100644 --- a/src/plugins/android/androiddevice.h +++ b/src/plugins/android/androiddevice.h @@ -78,6 +78,7 @@ public: IDevice::DeviceState getDeviceState(const QString &serial, IDevice::MachineType type) const; void updateDeviceState(const ProjectExplorer::IDevice::ConstPtr &device); + Utils::expected_str createAvd(const CreateAvdInfo &info, bool force); void startAvd(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent = nullptr); void eraseAvd(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent = nullptr); void setupWifiForDevice(const ProjectExplorer::IDevice::Ptr &device, QWidget *parent = nullptr); diff --git a/src/plugins/android/avddialog.cpp b/src/plugins/android/avddialog.cpp index 2e439c339ca..14064b3204d 100644 --- a/src/plugins/android/avddialog.cpp +++ b/src/plugins/android/avddialog.cpp @@ -131,53 +131,18 @@ int AvdDialog::exec() return QDialog::Rejected; } - CommandLine cmd(androidConfig().avdManagerToolPath(), {"create", "avd", "-n", name()}); - cmd.addArgs({"-k", si->sdkStylePath()}); - if (sdcardSize() > 0) - cmd.addArgs({"-c", QString("%1M").arg(sdcardSize())}); - - const QString deviceDef = deviceDefinition(); - if (!deviceDef.isEmpty() && deviceDef != "Custom") - cmd.addArgs({"-d", deviceDef}); - - if (m_overwriteCheckBox->isChecked()) - cmd.addArg("-f"); - - Process process; - process.setProcessMode(ProcessMode::Writer); - process.setEnvironment(androidConfig().toolsEnvironment()); - process.setCommand(cmd); - process.setWriteData("yes\n"); // yes to "Do you wish to create a custom hardware profile" - - QByteArray buffer; - QObject::connect(&process, &Process::readyReadStandardOutput, &process, [&process, &buffer] { - // This interaction is needed only if there is no "-d" arg for the avdmanager command. - buffer += process.readAllRawStandardOutput(); - if (buffer.endsWith(QByteArray("]:"))) { - // truncate to last line - const int index = buffer.lastIndexOf('\n'); - if (index != -1) - buffer = buffer.mid(index); - if (buffer.contains("hw.gpu.enabled")) - process.write("yes\n"); - else - process.write("\n"); - buffer.clear(); - } - }); - - using namespace std::chrono_literals; - process.runBlocking(10s, EventLoopMode::On); - if (process.result() != ProcessResult::FinishedWithSuccess) { + const CreateAvdInfo avdInfo{si->sdkStylePath(), si->apiLevel(), name(), abi(), + deviceDefinition(), sdcardSize()}; + const auto result = AndroidDeviceManager::instance()->createAvd( + avdInfo, m_overwriteCheckBox->isChecked()); + if (!result) { QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("Create new AVD"), - process.exitMessage()); + result.error()); return QDialog::Rejected; } - m_createdAvdInfo = {si->sdkStylePath(), si->apiLevel(), name(), abi(), deviceDef, - sdcardSize()}; + m_createdAvdInfo = avdInfo; AndroidDeviceManager::instance()->updateAvdsList(); } - return execResult; }