Detect iOS 17 device development status via devicectl

iOS 17 devices no longer report the development status via
the com.apple.xcode.developerdomain domain.

Task-number: QTCREATORBUG-29682
Change-Id: I9de3c88425b71906f51d0f0e8b6a4ece0e08eb3a
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Tor Arne Vestbø
2023-10-02 16:09:46 +02:00
committed by Eike Ziller
parent 3fdea38f58
commit 4f9cf826d6

View File

@@ -21,6 +21,7 @@
#include <QTimer> #include <QTimer>
#include <QUrl> #include <QUrl>
#include <QVersionNumber> #include <QVersionNumber>
#include <QJsonDocument>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
@@ -104,6 +105,20 @@ static bool findXcodePath(QString *xcodePath)
return (process.exitStatus() == QProcess::NormalExit && QFile::exists(*xcodePath)); return (process.exitStatus() == QProcess::NormalExit && QFile::exists(*xcodePath));
} }
static bool checkDevelopmentStatusViaDeviceCtl(const QString &deviceId)
{
QProcess process;
process.start("/usr/bin/xcrun", QStringList({"devicectl",
"device", "info", "details", "--quiet", "--device", deviceId, "-j", "-"}));
if (!process.waitForFinished(3000)) {
qCWarning(loggingCategory) << "Failed to launch devicectl:" << process.errorString();
return false;
}
auto jsonOutput = QJsonDocument::fromJson(process.readAllStandardOutput());
return jsonOutput["result"]["deviceProperties"]["developerModeStatus"] == "enabled";
}
/*! /*!
* \brief Finds the \e DeveloperDiskImage.dmg path corresponding to \a versionStr and \a buildStr. * \brief Finds the \e DeveloperDiskImage.dmg path corresponding to \a versionStr and \a buildStr.
* *
@@ -1668,13 +1683,20 @@ void DevInfoSession::deviceCallbackReturned()
if (!failure) { if (!failure) {
res[deviceConnectedKey] = QLatin1String("YES"); res[deviceConnectedKey] = QLatin1String("YES");
res[deviceNameKey] = getStringValue(device, nullptr, CFSTR("DeviceName")); res[deviceNameKey] = getStringValue(device, nullptr, CFSTR("DeviceName"));
res[uniqueDeviceId] = getStringValue(device, nullptr, CFSTR("UniqueDeviceID"));
const QString productVersion = getStringValue(device, nullptr, CFSTR("ProductVersion"));
if (productVersion.startsWith("17.")) {
res[developerStatusKey] = checkDevelopmentStatusViaDeviceCtl(res[uniqueDeviceId])
? QLatin1String("Development") : QLatin1String("*off*");
} else {
res[developerStatusKey] = getStringValue(device, res[developerStatusKey] = getStringValue(device,
CFSTR("com.apple.xcode.developerdomain"), CFSTR("com.apple.xcode.developerdomain"),
CFSTR("DeveloperStatus"), CFSTR("DeveloperStatus"),
"*off*"); "*off*");
}
res[cpuArchitectureKey] = getStringValue(device, nullptr, CFSTR("CPUArchitecture")); res[cpuArchitectureKey] = getStringValue(device, nullptr, CFSTR("CPUArchitecture"));
res[uniqueDeviceId] = getStringValue(device, nullptr, CFSTR("UniqueDeviceID"));
const QString productVersion = getStringValue(device, nullptr, CFSTR("ProductVersion"));
const QString buildVersion = getStringValue(device, nullptr, CFSTR("BuildVersion")); const QString buildVersion = getStringValue(device, nullptr, CFSTR("BuildVersion"));
if (!productVersion.isEmpty() && !buildVersion.isEmpty()) if (!productVersion.isEmpty() && !buildVersion.isEmpty())
res[osVersionKey] = QString("%1 (%2)").arg(productVersion, buildVersion); res[osVersionKey] = QString("%1 (%2)").arg(productVersion, buildVersion);