forked from qt-creator/qt-creator
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:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user