forked from qt-creator/qt-creator
Android: fix avdmanager parsing error for some new device types
Currently avdmanager tool can give an error "Error: Google <device> no longer exists as a device", due to missing definition for new devices in device.xml. This change temporarily removes the tag "hw.device.manufacturer" to parse successfully, then recover it back. Task-number: QTCREATORBUG-23284 Change-Id: I9c6f4b432d7c5d16944c9b620c4a4ecda473d45a Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -378,14 +378,60 @@ bool AndroidAvdManager::waitForBooted(const QString &serialNumber,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Currenly avdmanager tool fails to parse some AVDs because the correct
|
||||
* device definitions at devices.xml does not have some of the newest devices.
|
||||
* Particularly, failing because of tag "hw.device.manufacturer", thus removing
|
||||
* it would make paring successful. However, it has to be returned afterwards,
|
||||
* otherwise, Android Studio would give an error during parsing also. So this fix
|
||||
* aim to keep support for Qt Creator and Android Studio.
|
||||
*/
|
||||
static const QString avdManufacturerError = "no longer exists as a device";
|
||||
static QStringList avdErrorPaths;
|
||||
|
||||
static void AvdConfigEditManufacturerTag(const QString &avdPathStr, bool recoverMode = false)
|
||||
{
|
||||
const Utils::FilePath avdPath = Utils::FilePath::fromString(avdPathStr);
|
||||
if (avdPath.exists()) {
|
||||
const QString configFilePath = avdPath.pathAppended("config.ini").toString();
|
||||
QFile configFile(configFilePath);
|
||||
if (configFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
QString newContent;
|
||||
QTextStream textStream(&configFile);
|
||||
while (!textStream.atEnd()) {
|
||||
QString line = textStream.readLine();
|
||||
if (!line.contains("hw.device.manufacturer"))
|
||||
newContent.append(line + "\n");
|
||||
else if (recoverMode)
|
||||
newContent.append(line.replace("#", "") + "\n");
|
||||
else
|
||||
newContent.append("#" + line + "\n");
|
||||
}
|
||||
configFile.resize(0);
|
||||
textStream << newContent;
|
||||
configFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AndroidDeviceInfoList AvdManagerOutputParser::listVirtualDevices(const AndroidConfig &config)
|
||||
{
|
||||
QString output;
|
||||
if (!avdManagerCommand(config, {"list", "avd"}, &output)) {
|
||||
qCDebug(avdManagerLog) << "Avd list command failed" << output << config.sdkToolsVersion();
|
||||
return {};
|
||||
}
|
||||
return parseAvdList(output);
|
||||
AndroidDeviceInfoList avdList;
|
||||
|
||||
do {
|
||||
if (!avdManagerCommand(config, {"list", "avd"}, &output)) {
|
||||
qCDebug(avdManagerLog)
|
||||
<< "Avd list command failed" << output << config.sdkToolsVersion();
|
||||
return {};
|
||||
}
|
||||
|
||||
avdList = parseAvdList(output);
|
||||
} while (output.contains(avdManufacturerError));
|
||||
|
||||
for (const QString &avdPathStr : avdErrorPaths)
|
||||
AvdConfigEditManufacturerTag(avdPathStr, true);
|
||||
|
||||
return avdList;
|
||||
}
|
||||
|
||||
AndroidDeviceInfoList AvdManagerOutputParser::parseAvdList(const QString &output)
|
||||
@@ -394,7 +440,15 @@ AndroidDeviceInfoList AvdManagerOutputParser::parseAvdList(const QString &output
|
||||
QStringList avdInfo;
|
||||
auto parseAvdInfo = [&avdInfo, &avdList, this] () {
|
||||
AndroidDeviceInfo avd;
|
||||
if (parseAvd(avdInfo, &avd)) {
|
||||
if (!avdInfo.filter(avdManufacturerError).isEmpty()) {
|
||||
for (const QString &line : avdInfo) {
|
||||
QString value;
|
||||
if (valueForKey(avdInfoPathKey, line, &value)) {
|
||||
avdErrorPaths.append(value);
|
||||
AvdConfigEditManufacturerTag(value);
|
||||
}
|
||||
}
|
||||
} else if (parseAvd(avdInfo, &avd)) {
|
||||
// armeabi-v7a devices can also run armeabi code
|
||||
if (avd.cpuAbi.contains("armeabi-v7a"))
|
||||
avd.cpuAbi << "armeabi";
|
||||
@@ -407,12 +461,11 @@ AndroidDeviceInfoList AvdManagerOutputParser::parseAvdList(const QString &output
|
||||
avdInfo.clear();
|
||||
};
|
||||
|
||||
foreach (QString line, output.split('\n')) {
|
||||
if (line.startsWith("---------") || line.isEmpty()) {
|
||||
for (const QString &line : output.split('\n')) {
|
||||
if (line.startsWith("---------") || line.isEmpty())
|
||||
parseAvdInfo();
|
||||
} else {
|
||||
else
|
||||
avdInfo << line;
|
||||
}
|
||||
}
|
||||
|
||||
if (!avdInfo.isEmpty())
|
||||
@@ -426,7 +479,7 @@ AndroidDeviceInfoList AvdManagerOutputParser::parseAvdList(const QString &output
|
||||
bool AvdManagerOutputParser::parseAvd(const QStringList &deviceInfo, AndroidDeviceInfo *avd)
|
||||
{
|
||||
QTC_ASSERT(avd, return false);
|
||||
foreach (const QString &line, deviceInfo) {
|
||||
for (const QString &line : deviceInfo) {
|
||||
QString value;
|
||||
if (valueForKey(avdInfoErrorKey, line)) {
|
||||
qCDebug(avdManagerLog) << "Avd Parsing: Skip avd device. Error key found:" << line;
|
||||
|
||||
Reference in New Issue
Block a user