iOS Device: Show some more information in device options

Show iOS device name, identifier, OS version and cpu architecture.

Task-number: QTCREATORBUG-23016
Change-Id: I5fff2986a173800dabc585f17830cc242e436457
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Eike Ziller
2020-07-10 14:40:38 +02:00
parent 72bf4cd15f
commit f4af71a3dd
3 changed files with 90 additions and 78 deletions

View File

@@ -24,18 +24,21 @@
****************************************************************************/ ****************************************************************************/
#include "iosdevice.h" #include "iosdevice.h"
#include "iossimulator.h"
#include "iosconstants.h"
#include "iosconfigurations.h" #include "iosconfigurations.h"
#include "iosconstants.h"
#include "iossimulator.h"
#include "iostoolhandler.h" #include "iostoolhandler.h"
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/kitinformation.h>
#include <coreplugin/helpmanager.h> #include <coreplugin/helpmanager.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/devicesupport/idevicewidget.h>
#include <projectexplorer/kitinformation.h>
#include <utils/portlist.h> #include <utils/portlist.h>
#include <QFormLayout>
#include <QLabel>
#include <QMessageBox>
#include <QVariant> #include <QVariant>
#include <QVariantMap> #include <QVariantMap>
#include <QMessageBox>
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
@@ -57,6 +60,9 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
static const char kDeviceName[] = "deviceName";
static const char kUniqueDeviceId[] = "uniqueDeviceId";
namespace { namespace {
static Q_LOGGING_CATEGORY(detectLog, "qtc.ios.deviceDetect", QtWarningMsg) static Q_LOGGING_CATEGORY(detectLog, "qtc.ios.deviceDetect", QtWarningMsg)
} }
@@ -87,6 +93,14 @@ static QString CFStringRef2QString(CFStringRef s)
namespace Ios { namespace Ios {
namespace Internal { namespace Internal {
class IosDeviceInfoWidget : public IDeviceWidget
{
public:
IosDeviceInfoWidget(const ProjectExplorer::IDevice::Ptr &device);
void updateDeviceFromUi() {}
};
IosDevice::IosDevice(CtorHelper) IosDevice::IosDevice(CtorHelper)
: m_lastPort(Constants::IOS_DEVICE_PORT_START) : m_lastPort(Constants::IOS_DEVICE_PORT_START)
{ {
@@ -128,7 +142,7 @@ IDevice::DeviceInfo IosDevice::deviceInformation() const
IDeviceWidget *IosDevice::createWidget() IDeviceWidget *IosDevice::createWidget()
{ {
return nullptr; return new IosDeviceInfoWidget(sharedFromThis());
} }
DeviceProcessSignalOperation::Ptr IosDevice::signalOperation() const DeviceProcessSignalOperation::Ptr IosDevice::signalOperation() const
@@ -156,11 +170,21 @@ QVariantMap IosDevice::toMap() const
return res; return res;
} }
QString IosDevice::deviceName() const
{
return m_extraInfo.value(kDeviceName);
}
QString IosDevice::uniqueDeviceID() const QString IosDevice::uniqueDeviceID() const
{ {
return id().suffixAfter(Utils::Id(Constants::IOS_DEVICE_ID)); return id().suffixAfter(Utils::Id(Constants::IOS_DEVICE_ID));
} }
QString IosDevice::uniqueInternalDeviceId() const
{
return m_extraInfo.value(kUniqueDeviceId);
}
QString IosDevice::name() QString IosDevice::name()
{ {
return QCoreApplication::translate("Ios::Internal::IosDevice", "iOS Device"); return QCoreApplication::translate("Ios::Internal::IosDevice", "iOS Device");
@@ -198,7 +222,7 @@ IosDeviceManager::TranslationMap IosDeviceManager::translationMap()
if (translationMap) if (translationMap)
return *translationMap; return *translationMap;
TranslationMap &tMap = *new TranslationMap; TranslationMap &tMap = *new TranslationMap;
tMap[QLatin1String("deviceName")] = tr("Device name"); tMap[kDeviceName] = tr("Device name");
//: Whether the device is in developer mode. //: Whether the device is in developer mode.
tMap[QLatin1String("developerStatus")] = tr("Developer status"); tMap[QLatin1String("developerStatus")] = tr("Developer status");
tMap[QLatin1String("deviceConnected")] = tr("Connected"); tMap[QLatin1String("deviceConnected")] = tr("Connected");
@@ -248,7 +272,7 @@ void IosDeviceManager::deviceDisconnected(const QString &uid)
} else { } else {
auto iosDev = static_cast<const IosDevice *>(dev.data()); auto iosDev = static_cast<const IosDevice *>(dev.data());
if (iosDev->m_extraInfo.isEmpty() if (iosDev->m_extraInfo.isEmpty()
|| iosDev->m_extraInfo.value(QLatin1String("deviceName")) == QLatin1String("*unknown*")) { || iosDev->m_extraInfo.value(kDeviceName) == QLatin1String("*unknown*")) {
devManager->removeDevice(iosDev->id()); devManager->removeDevice(iosDev->id());
} else if (iosDev->deviceState() != IDevice::DeviceDisconnected) { } else if (iosDev->deviceState() != IDevice::DeviceDisconnected) {
qCDebug(detectLog) << "disconnecting device " << iosDev->uniqueDeviceID(); qCDebug(detectLog) << "disconnecting device " << iosDev->uniqueDeviceID();
@@ -290,9 +314,8 @@ void IosDeviceManager::deviceInfo(IosToolHandler *, const QString &uid,
newDev = new IosDevice(uid); newDev = new IosDevice(uid);
} }
if (!skipUpdate) { if (!skipUpdate) {
QString devNameKey = QLatin1String("deviceName"); if (info.contains(kDeviceName))
if (info.contains(devNameKey)) newDev->setDisplayName(info.value(kDeviceName));
newDev->setDisplayName(info.value(devNameKey));
newDev->m_extraInfo = info; newDev->m_extraInfo = info;
qCDebug(detectLog) << "updated info of ios device " << uid; qCDebug(detectLog) << "updated info of ios device " << uid;
dev = IDevice::ConstPtr(newDev); dev = IDevice::ConstPtr(newDev);
@@ -551,11 +574,24 @@ IosDeviceFactory::IosDeviceFactory()
bool IosDeviceFactory::canRestore(const QVariantMap &map) const bool IosDeviceFactory::canRestore(const QVariantMap &map) const
{ {
QVariantMap vMap = map.value(QLatin1String(Constants::EXTRA_INFO_KEY)).toMap(); QVariantMap vMap = map.value(QLatin1String(Constants::EXTRA_INFO_KEY)).toMap();
if (vMap.isEmpty() if (vMap.isEmpty() || vMap.value(kDeviceName).toString() == QLatin1String("*unknown*"))
|| vMap.value(QLatin1String("deviceName")).toString() == QLatin1String("*unknown*"))
return false; // transient device (probably generated during an activation) return false; // transient device (probably generated during an activation)
return true; return true;
} }
IosDeviceInfoWidget::IosDeviceInfoWidget(const IDevice::Ptr &device)
: IDeviceWidget(device)
{
const auto iosDevice = qSharedPointerCast<IosDevice>(device);
const auto formLayout = new QFormLayout(this);
formLayout->setContentsMargins(0, 0, 0, 0);
setLayout(formLayout);
formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
formLayout->addRow(IosDevice::tr("Device name:"), new QLabel(iosDevice->deviceName()));
formLayout->addRow(IosDevice::tr("Identifier:"), new QLabel(iosDevice->uniqueInternalDeviceId()));
formLayout->addRow(IosDevice::tr("OS Version:"), new QLabel(iosDevice->osVersion()));
formLayout->addRow(IosDevice::tr("CPU Architecture:"), new QLabel(iosDevice->cpuArchitecture()));
}
} // namespace Internal } // namespace Internal
} // namespace Ios } // namespace Ios

View File

@@ -57,7 +57,9 @@ public:
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override; QVariantMap toMap() const override;
QString deviceName() const;
QString uniqueDeviceID() const; QString uniqueDeviceID() const;
QString uniqueInternalDeviceId() const;
QString osVersion() const; QString osVersion() const;
QString cpuArchitecture() const; QString cpuArchitecture() const;
Utils::Port nextPort() const; Utils::Port nextPort() const;

View File

@@ -452,6 +452,10 @@ public:
void deviceCallbackReturned(); void deviceCallbackReturned();
QString commandName(); QString commandName();
QString getStringValue(AMDevice *device,
CFStringRef domain,
CFStringRef key,
const QString &fallback = QString());
}; };
class AppOpSession: public CommandSession { class AppOpSession: public CommandSession {
@@ -1584,82 +1588,52 @@ QString DevInfoSession::commandName()
return QString::fromLatin1("DevInfoSession(%1, %2)").arg(deviceId); return QString::fromLatin1("DevInfoSession(%1, %2)").arg(deviceId);
} }
QString DevInfoSession::getStringValue(AMDevice *device,
CFStringRef domain,
CFStringRef key,
const QString &fallback)
{
QString value = fallback;
CFPropertyListRef cfValue = lib()->deviceCopyValue(device, domain, key);
if (cfValue) {
if (CFGetTypeID(cfValue) == CFStringGetTypeID())
value = QString::fromCFString(reinterpret_cast<CFStringRef>(cfValue));
CFRelease(cfValue);
}
return value;
}
void DevInfoSession::deviceCallbackReturned() void DevInfoSession::deviceCallbackReturned()
{ {
if (debugAll) if (debugAll)
qDebug() << "device available"; qDebug() << "device available";
QMap<QString,QString> res; QMap<QString,QString> res;
QString deviceNameKey = QLatin1String("deviceName"); const QString deviceNameKey = "deviceName";
QString developerStatusKey = QLatin1String("developerStatus"); const QString developerStatusKey = "developerStatus";
QString deviceConnectedKey = QLatin1String("deviceConnected"); const QString deviceConnectedKey = "deviceConnected";
QString osVersionKey = QLatin1String("osVersion"); const QString osVersionKey = "osVersion";
QString cpuArchitectureKey = "cpuArchitecture"; const QString cpuArchitectureKey = "cpuArchitecture";
const QString uniqueDeviceId = "uniqueDeviceId";
bool failure = !device; bool failure = !device;
if (!failure) { if (!failure) {
failure = !connectDevice(); failure = !connectDevice();
if (!failure) { if (!failure) {
res[deviceConnectedKey] = QLatin1String("YES"); res[deviceConnectedKey] = QLatin1String("YES");
CFPropertyListRef cfDeviceName = lib()->deviceCopyValue(device, 0, res[deviceNameKey] = getStringValue(device, nullptr, CFSTR("DeviceName"));
CFSTR("DeviceName")); res[developerStatusKey] = getStringValue(device,
// CFShow(cfDeviceName); CFSTR("com.apple.xcode.developerdomain"),
if (cfDeviceName) { CFSTR("DeveloperStatus"),
if (CFGetTypeID(cfDeviceName) == CFStringGetTypeID()) "*off*");
res[deviceNameKey] = QString::fromCFString(reinterpret_cast<CFStringRef>(cfDeviceName)); res[cpuArchitectureKey] = getStringValue(device, nullptr, CFSTR("CPUArchitecture"));
CFRelease(cfDeviceName); res[uniqueDeviceId] = getStringValue(device, nullptr, CFSTR("UniqueDeviceID"));
} const QString productVersion = getStringValue(device, nullptr, CFSTR("ProductVersion"));
if (!res.contains(deviceNameKey)) const QString buildVersion = getStringValue(device, nullptr, CFSTR("BuildVersion"));
res[deviceNameKey] = QString(); if (!productVersion.isEmpty() && !buildVersion.isEmpty())
} res[osVersionKey] = QString("%1 (%2)").arg(productVersion, buildVersion);
if (!failure) { else if (!productVersion.isEmpty())
CFPropertyListRef cfDevStatus = lib()->deviceCopyValue(device, res[osVersionKey] = productVersion;
CFSTR("com.apple.xcode.developerdomain"),
CFSTR("DeveloperStatus"));
// CFShow(cfDevStatus);
if (cfDevStatus) {
if (CFGetTypeID(cfDevStatus) == CFStringGetTypeID())
res[developerStatusKey] = QString::fromCFString(reinterpret_cast<CFStringRef>(cfDevStatus));
CFRelease(cfDevStatus);
}
if (!res.contains(developerStatusKey))
res[developerStatusKey] = QLatin1String("*off*");
}
if (!failure) {
CFPropertyListRef cfProductVersion = lib()->deviceCopyValue(device,
0,
CFSTR("ProductVersion"));
//CFShow(cfProductVersion);
CFPropertyListRef cfBuildVersion = lib()->deviceCopyValue(device,
0,
CFSTR("BuildVersion"));
//CFShow(cfBuildVersion);
CFPropertyListRef cfCpuArchitecture = lib()->deviceCopyValue(device,
0,
CFSTR("CPUArchitecture"));
//CFShow(cfCpuArchitecture);
if (cfCpuArchitecture) {
if (CFGetTypeID(cfCpuArchitecture) == CFStringGetTypeID()) {
res[cpuArchitectureKey] = QString::fromCFString(
reinterpret_cast<CFStringRef>(cfCpuArchitecture));
}
CFRelease(cfCpuArchitecture);
}
//CFShow(cfBuildVersion);
QString versionString;
if (cfProductVersion) {
if (CFGetTypeID(cfProductVersion) == CFStringGetTypeID())
versionString = QString::fromCFString(reinterpret_cast<CFStringRef>(cfProductVersion));
CFRelease(cfProductVersion);
}
if (cfBuildVersion) {
if (!versionString.isEmpty() && CFGetTypeID(cfBuildVersion) == CFStringGetTypeID())
versionString += QString::fromLatin1(" (%1)").arg(
QString::fromCFString(reinterpret_cast<CFStringRef>(cfBuildVersion)));
CFRelease(cfBuildVersion);
}
if (!versionString.isEmpty())
res[osVersionKey] = versionString;
else else
res[osVersionKey] = QLatin1String("*unknown*"); res[osVersionKey] = "*unknown*";
} }
disconnectDevice(); disconnectDevice();
} }