forked from qt-creator/qt-creator
ios: preliminary support for ios
first work in progress support for ios * separate iosTool using xml communication used for device info and run * iossim tool to handle the simulator * debug prepared but not working * separate gcc toolchain detection fix for simulator 1) add a QT built for ios 2) open a project, for example qtbase/examples/widgets/animation/animatedtiles/animatedtiles.pro 3) build/run... Change-Id: I7e01604e416338cbe4692dfb34f5d3f31312702d Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
committed by
Eike Ziller
parent
3a7d91ca44
commit
8d96ce557e
519
src/plugins/ios/iosdevice.cpp
Normal file
519
src/plugins/ios/iosdevice.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "iosdevice.h"
|
||||
#include "iosconstants.h"
|
||||
#include "iosconfigurations.h"
|
||||
#include "iostoolhandler.h"
|
||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVariant>
|
||||
#include <QVariantMap>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
static bool debugDeviceDetection = false;
|
||||
|
||||
namespace {
|
||||
QString CFStringRef2QString(CFStringRef s)
|
||||
{
|
||||
unsigned char buf[250];
|
||||
CFIndex len = CFStringGetLength(s);
|
||||
CFIndex usedBufLen;
|
||||
CFIndex converted = CFStringGetBytes(s, CFRangeMake(0,len), kCFStringEncodingUTF8,
|
||||
'?', false, &buf[0], sizeof(buf), &usedBufLen);
|
||||
if (converted == len)
|
||||
return QString::fromUtf8(reinterpret_cast<char *>(&buf[0]), usedBufLen);
|
||||
size_t bufSize = sizeof(buf)
|
||||
+ CFStringGetMaximumSizeForEncoding(len - converted, kCFStringEncodingUTF8);
|
||||
unsigned char *bigBuf = new unsigned char[bufSize];
|
||||
memcpy(bigBuf, buf, usedBufLen);
|
||||
CFIndex newUseBufLen;
|
||||
CFStringGetBytes(s, CFRangeMake(converted,len), kCFStringEncodingUTF8,
|
||||
'?', false, &bigBuf[usedBufLen], bufSize, &newUseBufLen);
|
||||
QString res = QString::fromUtf8(reinterpret_cast<char *>(bigBuf), usedBufLen + newUseBufLen);
|
||||
delete[] bigBuf;
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Ios {
|
||||
namespace Internal {
|
||||
|
||||
const char extraInfoKey[] = "extraInfo";
|
||||
|
||||
IosDevice::IosDevice()
|
||||
: IDevice(Core::Id(Constants::IOS_DEVICE_TYPE),
|
||||
IDevice::AutoDetected,
|
||||
IDevice::Hardware,
|
||||
Constants::IOS_DEVICE_ID)
|
||||
{
|
||||
setDisplayName(QCoreApplication::translate("Ios::Internal::IosDevice", "iOS Device"));
|
||||
setDeviceState(DeviceStateUnknown);
|
||||
}
|
||||
|
||||
IosDevice::IosDevice(const IosDevice &other)
|
||||
: IDevice(other), m_extraInfo(other.m_extraInfo), m_ignoreDevice(other.m_ignoreDevice)
|
||||
{ }
|
||||
|
||||
IosDevice::IosDevice(const QString &uid)
|
||||
: IDevice(Core::Id(Constants::IOS_DEVICE_TYPE),
|
||||
IDevice::AutoDetected,
|
||||
IDevice::Hardware,
|
||||
Core::Id(Constants::IOS_DEVICE_ID).withSuffix(uid))
|
||||
{
|
||||
setDisplayName(QCoreApplication::translate("Ios::Internal::IosDevice", "iOS Device"));
|
||||
setDeviceState(DeviceStateUnknown);
|
||||
}
|
||||
|
||||
|
||||
IDevice::DeviceInfo IosDevice::deviceInformation() const
|
||||
{
|
||||
IDevice::DeviceInfo res;
|
||||
QMapIterator<QString, QString> i(m_extraInfo);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
IosDeviceManager::TranslationMap tMap = IosDeviceManager::translationMap();
|
||||
if (tMap.contains(i.key()))
|
||||
res.append(DeviceInfoItem(tMap.value(i.key()), tMap.value(i.value(), i.value())));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
QString IosDevice::displayType() const
|
||||
{
|
||||
return QCoreApplication::translate("Ios::Internal::IosDevice", "iOS");
|
||||
}
|
||||
|
||||
IDeviceWidget *IosDevice::createWidget()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<Core::Id> IosDevice::actionIds() const
|
||||
{
|
||||
return QList<Core::Id>(); // add activation action?
|
||||
}
|
||||
|
||||
QString IosDevice::displayNameForActionId(Core::Id actionId) const
|
||||
{
|
||||
Q_UNUSED(actionId)
|
||||
return QString();
|
||||
}
|
||||
|
||||
void IosDevice::executeAction(Core::Id actionId, QWidget *parent)
|
||||
{
|
||||
Q_UNUSED(actionId)
|
||||
Q_UNUSED(parent)
|
||||
}
|
||||
|
||||
DeviceProcessSignalOperation::Ptr IosDevice::signalOperation() const
|
||||
{
|
||||
return DeviceProcessSignalOperation::Ptr();
|
||||
}
|
||||
|
||||
IDevice::Ptr IosDevice::clone() const
|
||||
{
|
||||
return IDevice::Ptr(new IosDevice(*this));
|
||||
}
|
||||
|
||||
void IosDevice::fromMap(const QVariantMap &map)
|
||||
{
|
||||
IDevice::fromMap(map);
|
||||
QVariantMap vMap = map.value(QLatin1String(extraInfoKey)).toMap();
|
||||
QMapIterator<QString, QVariant> i(vMap);
|
||||
m_extraInfo.clear();
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
m_extraInfo.insert(i.key(), i.value().toString());
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap IosDevice::toMap() const
|
||||
{
|
||||
QVariantMap res = IDevice::toMap();
|
||||
QVariantMap vMap;
|
||||
QMapIterator<QString, QString> i(m_extraInfo);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
vMap.insert(i.key(), i.value());
|
||||
}
|
||||
res.insert(QLatin1String(extraInfoKey), vMap);
|
||||
return res;
|
||||
}
|
||||
|
||||
QString IosDevice::uniqueDeviceID() const
|
||||
{
|
||||
return id().suffixAfter(Core::Id(Constants::IOS_DEVICE_ID));
|
||||
}
|
||||
/*
|
||||
// add back?
|
||||
|
||||
QString IosDevice::cpuArchitecure() const
|
||||
{
|
||||
return m_extraInfo.value(QLatin1String("deviceInfo")).toMap()
|
||||
.value(QLatin1String("CPUArchitecture")).toString();
|
||||
}
|
||||
|
||||
QString IosDevice::productType() const
|
||||
{
|
||||
return m_extraInfo.value(QLatin1String("deviceInfo")).toMap()
|
||||
.value(QLatin1String("ProductType")).toString();
|
||||
}*/
|
||||
|
||||
|
||||
// IosDeviceManager
|
||||
|
||||
IosDeviceManager::TranslationMap IosDeviceManager::translationMap()
|
||||
{
|
||||
static TranslationMap *translationMap = 0;
|
||||
if (translationMap)
|
||||
return *translationMap;
|
||||
TranslationMap &tMap = *new TranslationMap;
|
||||
tMap[QLatin1String("deviceName")] = tr("Device name");
|
||||
tMap[QLatin1String("developerStatus")] = tr("Developer status");
|
||||
tMap[QLatin1String("deviceConnected")] = tr("Connected");
|
||||
tMap[QLatin1String("YES")] = tr("yes");
|
||||
tMap[QLatin1String("NO")] = tr("no");
|
||||
tMap[QLatin1String("YES")] = tr("yes");
|
||||
tMap[QLatin1String("*unknown*")] = tr("unknown");
|
||||
translationMap = &tMap;
|
||||
return tMap;
|
||||
}
|
||||
|
||||
void IosDeviceManager::deviceConnected(const QString &uid, const QString &name)
|
||||
{
|
||||
DeviceManager *devManager = DeviceManager::instance();
|
||||
Core::Id baseDevId(Constants::IOS_DEVICE_ID);
|
||||
Core::Id devType(Constants::IOS_DEVICE_TYPE);
|
||||
Core::Id devId = baseDevId.withSuffix(uid);
|
||||
IDevice::ConstPtr dev = devManager->find(devId);
|
||||
if (dev.isNull()) {
|
||||
IosDevice *newDev = new IosDevice(uid);
|
||||
if (!name.isNull())
|
||||
newDev->setDisplayName(name);
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "adding ios device " << uid;
|
||||
devManager->addDevice(IDevice::ConstPtr(newDev));
|
||||
} else if (dev->deviceState() != IDevice::DeviceConnected &&
|
||||
dev->deviceState() != IDevice::DeviceReadyToUse) {
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "updating ios device " << uid;
|
||||
IosDevice *newDev = 0;
|
||||
if (dev->type() == devType) {
|
||||
const IosDevice *iosDev = static_cast<const IosDevice *>(dev.data());
|
||||
newDev = new IosDevice(*iosDev);
|
||||
} else {
|
||||
newDev = new IosDevice(uid);
|
||||
}
|
||||
devManager->addDevice(IDevice::ConstPtr(newDev));
|
||||
}
|
||||
updateInfo(uid);
|
||||
}
|
||||
|
||||
void IosDeviceManager::deviceDisconnected(const QString &uid)
|
||||
{
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "detected disconnection of ios device " << uid;
|
||||
DeviceManager *devManager = DeviceManager::instance();
|
||||
Core::Id baseDevId(Constants::IOS_DEVICE_ID);
|
||||
Core::Id devType(Constants::IOS_DEVICE_TYPE);
|
||||
Core::Id devId = baseDevId.withSuffix(uid);
|
||||
IDevice::ConstPtr dev = devManager->find(devId);
|
||||
if (dev.isNull() || dev->type() != devType) {
|
||||
qDebug() << "ignoring disconnection of ios device " << uid; // should neve happen
|
||||
} else {
|
||||
const IosDevice *iosDev = static_cast<const IosDevice *>(dev.data());
|
||||
if (iosDev->deviceState() != IDevice::DeviceDisconnected) {
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "disconnecting device " << iosDev->uniqueDeviceID();
|
||||
devManager->setDeviceState(iosDev->id(), IDevice::DeviceDisconnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IosDeviceManager::updateInfo(const QString &devId)
|
||||
{
|
||||
IosToolHandler *requester = new IosToolHandler(IosToolHandler::IosDeviceType, this);
|
||||
connect(requester, SIGNAL(deviceInfo(Ios::IosToolHandler*,QString,Ios::IosToolHandler::Dict)),
|
||||
SLOT(deviceInfo(Ios::IosToolHandler *,QString,Ios::IosToolHandler::Dict)));
|
||||
connect(requester, SIGNAL(finished(Ios::IosToolHandler*)),
|
||||
SLOT(infoGathererFinished(Ios::IosToolHandler*)));
|
||||
requester->requestDeviceInfo(devId);
|
||||
}
|
||||
|
||||
void IosDeviceManager::deviceInfo(IosToolHandler *, const QString &uid,
|
||||
const Ios::IosToolHandler::Dict &info)
|
||||
{
|
||||
DeviceManager *devManager = DeviceManager::instance();
|
||||
Core::Id baseDevId(Constants::IOS_DEVICE_ID);
|
||||
Core::Id devType(Constants::IOS_DEVICE_TYPE);
|
||||
Core::Id devId = baseDevId.withSuffix(uid);
|
||||
IDevice::ConstPtr dev = devManager->find(devId);
|
||||
bool skipUpdate = false;
|
||||
IosDevice *newDev = 0;
|
||||
if (!dev.isNull() && dev->type() == devType) {
|
||||
const IosDevice *iosDev = static_cast<const IosDevice *>(dev.data());
|
||||
if (iosDev->m_extraInfo == info) {
|
||||
skipUpdate = true;
|
||||
newDev = const_cast<IosDevice *>(iosDev);
|
||||
} else {
|
||||
newDev = new IosDevice(*iosDev);
|
||||
}
|
||||
} else {
|
||||
newDev = new IosDevice(uid);
|
||||
}
|
||||
if (!skipUpdate) {
|
||||
QString devNameKey = QLatin1String("deviceName");
|
||||
if (info.contains(devNameKey))
|
||||
newDev->setDisplayName(info.value(devNameKey));
|
||||
newDev->m_extraInfo = info;
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "updated info of ios device " << uid;
|
||||
dev = IDevice::ConstPtr(newDev);
|
||||
devManager->addDevice(dev);
|
||||
}
|
||||
QLatin1String devStatusKey = QLatin1String("developerStatus");
|
||||
if (info.contains(devStatusKey)) {
|
||||
QString devStatus = info.value(devStatusKey);
|
||||
if (devStatus == QLatin1String("*off*")) {
|
||||
devManager->setDeviceState(newDev->id(), IDevice::DeviceConnected);
|
||||
if (!newDev->m_ignoreDevice && !IosConfigurations::instance().config().ignoreAllDevices) {
|
||||
QMessageBox mBox;
|
||||
mBox.setText(tr("An iOS device in user mode has been detected."));
|
||||
mBox.setInformativeText(tr("Do you want to see how to set it up for development?"));
|
||||
mBox.setStandardButtons(QMessageBox::NoAll | QMessageBox::No | QMessageBox::Yes);
|
||||
mBox.setDefaultButton(QMessageBox::No);
|
||||
int ret = mBox.exec();
|
||||
switch (ret) {
|
||||
case QMessageBox::Yes:
|
||||
// open doc
|
||||
break;
|
||||
case QMessageBox::No:
|
||||
newDev->m_ignoreDevice = true;
|
||||
break;
|
||||
case QMessageBox::NoAll:
|
||||
{
|
||||
IosConfig conf = IosConfigurations::instance().config();
|
||||
conf.ignoreAllDevices = true;
|
||||
IosConfigurations::instance().setConfig(conf);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (devStatus == QLatin1String("Development")) {
|
||||
devManager->setDeviceState(newDev->id(), IDevice::DeviceReadyToUse);
|
||||
} else {
|
||||
devManager->setDeviceState(newDev->id(), IDevice::DeviceConnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IosDeviceManager::infoGathererFinished(IosToolHandler *gatherer)
|
||||
{
|
||||
gatherer->deleteLater();
|
||||
}
|
||||
|
||||
namespace {
|
||||
io_iterator_t gAddedIter;
|
||||
io_iterator_t gRemovedIter;
|
||||
|
||||
extern "C" {
|
||||
void deviceConnectedCallback(void *refCon, io_iterator_t iterator)
|
||||
{
|
||||
kern_return_t kr;
|
||||
io_service_t usbDevice;
|
||||
(void) refCon;
|
||||
|
||||
while ((usbDevice = IOIteratorNext(iterator))) {
|
||||
io_name_t deviceName;
|
||||
|
||||
// Get the USB device's name.
|
||||
kr = IORegistryEntryGetName(usbDevice, deviceName);
|
||||
QString name;
|
||||
if (KERN_SUCCESS == kr)
|
||||
name = QString::fromLocal8Bit(deviceName);
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "ios device " << name << " in deviceAddedCallback";
|
||||
|
||||
CFStringRef cfUid = static_cast<CFStringRef>(IORegistryEntryCreateCFProperty(
|
||||
usbDevice,
|
||||
CFSTR(kUSBSerialNumberString),
|
||||
kCFAllocatorDefault, 0));
|
||||
QString uid = CFStringRef2QString(cfUid);
|
||||
CFRelease(cfUid);
|
||||
IosDeviceManager::instance()->deviceConnected(uid, name);
|
||||
|
||||
// Done with this USB device; release the reference added by IOIteratorNext
|
||||
kr = IOObjectRelease(usbDevice);
|
||||
}
|
||||
}
|
||||
|
||||
void deviceDisconnectedCallback(void *refCon, io_iterator_t iterator)
|
||||
{
|
||||
kern_return_t kr;
|
||||
io_service_t usbDevice;
|
||||
(void) refCon;
|
||||
|
||||
while ((usbDevice = IOIteratorNext(iterator))) {
|
||||
io_name_t deviceName;
|
||||
|
||||
// Get the USB device's name.
|
||||
kr = IORegistryEntryGetName(usbDevice, deviceName);
|
||||
if (KERN_SUCCESS != kr)
|
||||
deviceName[0] = '\0';
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "ios device " << deviceName << " in deviceDisconnectedCallback";
|
||||
|
||||
{
|
||||
CFStringRef cfUid = static_cast<CFStringRef>(IORegistryEntryCreateCFProperty(
|
||||
usbDevice,
|
||||
CFSTR(kUSBSerialNumberString),
|
||||
kCFAllocatorDefault, 0));
|
||||
QString uid = CFStringRef2QString(cfUid);
|
||||
CFRelease(cfUid);
|
||||
IosDeviceManager::instance()->deviceDisconnected(uid);
|
||||
}
|
||||
|
||||
// Done with this USB device; release the reference added by IOIteratorNext
|
||||
kr = IOObjectRelease(usbDevice);
|
||||
}
|
||||
}
|
||||
|
||||
} // extern C
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void IosDeviceManager::monitorAvailableDevices()
|
||||
{
|
||||
CFMutableDictionaryRef matchingDictionary =
|
||||
IOServiceMatching("IOUSBDevice" );
|
||||
{
|
||||
UInt32 vendorId = 0x05ac;
|
||||
CFNumberRef cfVendorValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type,
|
||||
&vendorId );
|
||||
CFDictionaryAddValue( matchingDictionary, CFSTR( kUSBVendorID ), cfVendorValue);
|
||||
CFRelease( cfVendorValue );
|
||||
UInt32 productId = 0x1280;
|
||||
CFNumberRef cfProductIdValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type,
|
||||
&productId );
|
||||
CFDictionaryAddValue( matchingDictionary, CFSTR( kUSBProductID ), cfProductIdValue);
|
||||
CFRelease( cfProductIdValue );
|
||||
UInt32 productIdMask = 0xFFC0;
|
||||
CFNumberRef cfProductIdMaskValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type,
|
||||
&productIdMask );
|
||||
CFDictionaryAddValue( matchingDictionary, CFSTR( kUSBProductIDMask ), cfProductIdMaskValue);
|
||||
CFRelease( cfProductIdMaskValue );
|
||||
}
|
||||
|
||||
IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
|
||||
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
|
||||
|
||||
// IOServiceAddMatchingNotification releases this, so we retain for the next call
|
||||
CFRetain(matchingDictionary);
|
||||
|
||||
// Now set up a notification to be called when a device is first matched by I/O Kit.
|
||||
kern_return_t kr;
|
||||
kr = IOServiceAddMatchingNotification(notificationPort,
|
||||
kIOMatchedNotification,
|
||||
matchingDictionary,
|
||||
deviceConnectedCallback,
|
||||
NULL,
|
||||
&gAddedIter);
|
||||
|
||||
|
||||
kr = IOServiceAddMatchingNotification(notificationPort,
|
||||
kIOTerminatedNotification,
|
||||
matchingDictionary,
|
||||
deviceDisconnectedCallback,
|
||||
NULL,
|
||||
&gRemovedIter);
|
||||
|
||||
// Iterate once to get already-present devices and arm the notification
|
||||
deviceConnectedCallback(NULL, gAddedIter);
|
||||
deviceDisconnectedCallback(NULL, gRemovedIter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
IosDeviceManager::IosDeviceManager(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
IosDeviceManager *IosDeviceManager::instance()
|
||||
{
|
||||
static IosDeviceManager obj;
|
||||
return &obj;
|
||||
}
|
||||
|
||||
void IosDeviceManager::updateAvailableDevices(const QStringList &devices)
|
||||
{
|
||||
foreach (const QString &uid, devices)
|
||||
deviceConnected(uid);
|
||||
|
||||
DeviceManager *devManager = DeviceManager::instance();
|
||||
for (int iDevice = 0; iDevice < devManager->deviceCount(); ++iDevice) {
|
||||
IDevice::ConstPtr dev = devManager->deviceAt(iDevice);
|
||||
Core::Id devType(Constants::IOS_DEVICE_TYPE);
|
||||
if (dev.isNull() || dev->type() != devType)
|
||||
continue;
|
||||
const IosDevice *iosDev = static_cast<const IosDevice *>(dev.data());
|
||||
if (devices.contains(iosDev->uniqueDeviceID()))
|
||||
continue;
|
||||
if (iosDev->deviceState() != IDevice::DeviceDisconnected) {
|
||||
if (debugDeviceDetection)
|
||||
qDebug() << "disconnecting device " << iosDev->uniqueDeviceID();
|
||||
devManager->setDeviceState(iosDev->id(), IDevice::DeviceDisconnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IosDevice::ConstPtr IosKitInformation::device(Kit *kit)
|
||||
{
|
||||
if (!kit)
|
||||
return IosDevice::ConstPtr();
|
||||
ProjectExplorer::IDevice::ConstPtr dev = ProjectExplorer::DeviceKitInformation::device(kit);
|
||||
IosDevice::ConstPtr res = dev.dynamicCast<const IosDevice>();
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Ios
|
||||
Reference in New Issue
Block a user