Android: Simplify listVirtualDevices()

Introduce ParsedAvdList struct and return it from the parseAvdList().
This eliminates passing the errorPaths result by reference.
Simplify listVirtualDevices() implementation by removing some local
variables.
Adapt the tst_AvdManagerOutputParser test accordingly.

Change-Id: If4670bcc81ce36416c1fe35e8ee57e822f82516f
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Jarek Kobus
2024-05-13 12:42:30 +02:00
parent 58f596e36a
commit 7af6722c07
4 changed files with 26 additions and 24 deletions

View File

@@ -72,8 +72,6 @@ static void avdConfigEditManufacturerTag(const FilePath &avdPath, bool recoverMo
static AndroidDeviceInfoList listVirtualDevices() static AndroidDeviceInfoList listVirtualDevices()
{ {
QString output;
AndroidDeviceInfoList avdList;
/* /*
Currenly avdmanager tool fails to parse some AVDs because the correct Currenly avdmanager tool fails to parse some AVDs because the correct
device definitions at devices.xml does not have some of the newest devices. device definitions at devices.xml does not have some of the newest devices.
@@ -83,26 +81,25 @@ static AndroidDeviceInfoList listVirtualDevices()
aim to keep support for Qt Creator and Android Studio. aim to keep support for Qt Creator and Android Studio.
*/ */
FilePaths allAvdErrorPaths; FilePaths allAvdErrorPaths;
FilePaths avdErrorPaths; while (true) {
QString output;
do {
if (!AndroidAvdManager::avdManagerCommand({"list", "avd"}, &output)) { if (!AndroidAvdManager::avdManagerCommand({"list", "avd"}, &output)) {
qCDebug(avdManagerLog) qCDebug(avdManagerLog)
<< "Avd list command failed" << output << androidConfig().sdkToolsVersion(); << "Avd list command failed" << output << androidConfig().sdkToolsVersion();
return {}; return {};
} }
avdErrorPaths.clear(); const auto parsedAvdList = parseAvdList(output);
avdList = parseAvdList(output, &avdErrorPaths); if (parsedAvdList.errorPaths.isEmpty()) {
allAvdErrorPaths << avdErrorPaths; for (const FilePath &avdPath : std::as_const(allAvdErrorPaths))
for (const FilePath &avdPath : std::as_const(avdErrorPaths)) avdConfigEditManufacturerTag(avdPath, true); // re-add manufacturer tag
return parsedAvdList.avdList;
}
allAvdErrorPaths << parsedAvdList.errorPaths;
for (const FilePath &avdPath : parsedAvdList.errorPaths)
avdConfigEditManufacturerTag(avdPath); // comment out manufacturer tag avdConfigEditManufacturerTag(avdPath); // comment out manufacturer tag
} while (!avdErrorPaths.isEmpty()); // try again }
return {};
for (const FilePath &avdPath : std::as_const(allAvdErrorPaths))
avdConfigEditManufacturerTag(avdPath, true); // re-add manufacturer tag
return avdList;
} }
QFuture<AndroidDeviceInfoList> AndroidAvdManager::avdList() const QFuture<AndroidDeviceInfoList> AndroidAvdManager::avdList() const

View File

@@ -86,10 +86,10 @@ static std::optional<AndroidDeviceInfo> parseAvd(const QStringList &deviceInfo)
return {}; return {};
} }
AndroidDeviceInfoList parseAvdList(const QString &output, Utils::FilePaths *avdErrorPaths) ParsedAvdList parseAvdList(const QString &output)
{ {
QTC_CHECK(avdErrorPaths);
AndroidDeviceInfoList avdList; AndroidDeviceInfoList avdList;
Utils::FilePaths errorPaths;
QStringList avdInfo; QStringList avdInfo;
using ErrorPath = Utils::FilePath; using ErrorPath = Utils::FilePath;
using AvdResult = std::variant<std::monostate, AndroidDeviceInfo, ErrorPath>; using AvdResult = std::variant<std::monostate, AndroidDeviceInfo, ErrorPath>;
@@ -120,14 +120,14 @@ AndroidDeviceInfoList parseAvdList(const QString &output, Utils::FilePaths *avdE
if (auto info = std::get_if<AndroidDeviceInfo>(&result)) if (auto info = std::get_if<AndroidDeviceInfo>(&result))
avdList << *info; avdList << *info;
else if (auto errorPath = std::get_if<ErrorPath>(&result)) else if (auto errorPath = std::get_if<ErrorPath>(&result))
*avdErrorPaths << *errorPath; errorPaths << *errorPath;
avdInfo.clear(); avdInfo.clear();
} else { } else {
avdInfo << line; avdInfo << line;
} }
} }
return Utils::sorted(std::move(avdList)); return {Utils::sorted(std::move(avdList)), errorPaths};
} }
int platformNameToApiLevel(const QString &platformName) int platformNameToApiLevel(const QString &platformName)

View File

@@ -10,7 +10,13 @@ namespace Internal {
const char avdManufacturerError[] = "no longer exists as a device"; const char avdManufacturerError[] = "no longer exists as a device";
AndroidDeviceInfoList parseAvdList(const QString &output, Utils::FilePaths *avdErrorPaths); struct ParsedAvdList
{
AndroidDeviceInfoList avdList;
Utils::FilePaths errorPaths;
};
ParsedAvdList parseAvdList(const QString &output);
int platformNameToApiLevel(const QString &platformName); int platformNameToApiLevel(const QString &platformName);
QString convertNameToExtension(const QString &name); QString convertNameToExtension(const QString &name);

View File

@@ -80,10 +80,9 @@ void tst_AvdManagerOutputParser::parse()
QFETCH(AndroidDeviceInfoList, output); QFETCH(AndroidDeviceInfoList, output);
QFETCH(Utils::FilePaths, errorPaths); QFETCH(Utils::FilePaths, errorPaths);
Utils::FilePaths avdErrorPaths; const auto result = parseAvdList(input);
const auto result = parseAvdList(input, &avdErrorPaths); QCOMPARE(result.avdList, output);
QCOMPARE(result, output); QCOMPARE(result.errorPaths, errorPaths);
QCOMPARE(avdErrorPaths, errorPaths);
} }
QTEST_GUILESS_MAIN(tst_AvdManagerOutputParser) QTEST_GUILESS_MAIN(tst_AvdManagerOutputParser)