From 30f9f68b156d860aa08840f1afc277c92cb26d8d Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 15 Jun 2022 12:08:07 +0200 Subject: [PATCH] iostool: Cleanup and improve debug output Replaced the custom command line arg parsing code with QCommandLineParser Change-Id: I14e8695b5ee327b1d111558271bf98afd0c942b0 Reviewed-by: Eike Ziller Reviewed-by: Qt CI Bot Reviewed-by: --- src/plugins/ios/iostoolhandler.cpp | 2 +- src/tools/iostool/CMakeLists.txt | 2 +- src/tools/iostool/gdbrunner.cpp | 16 +- src/tools/iostool/iosdevicemanager.cpp | 782 ++++++++++++++----------- src/tools/iostool/iostool.cpp | 319 +++++----- src/tools/iostool/iostool.h | 25 +- src/tools/iostool/main.cpp | 13 +- src/tools/iostool/mobiledevicelib.cpp | 216 +++---- src/tools/iostool/mobiledevicelib.h | 6 +- 9 files changed, 725 insertions(+), 656 deletions(-) diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp index 00fece4880a..3c7d374ed54 100644 --- a/src/plugins/ios/iostoolhandler.cpp +++ b/src/plugins/ios/iostoolhandler.cpp @@ -733,7 +733,7 @@ void IosDeviceToolHandlerPrivate::requestRunApp(const QString &bundlePath, args << QLatin1String("--debug"); break; } - args << QLatin1String("--args") << extraArgs; + args << QLatin1String("--") << extraArgs; op = OpAppRun; start(IosToolHandler::iosDeviceToolPath(), args); } diff --git a/src/tools/iostool/CMakeLists.txt b/src/tools/iostool/CMakeLists.txt index b7efdc1abda..bf9641108dd 100644 --- a/src/tools/iostool/CMakeLists.txt +++ b/src/tools/iostool/CMakeLists.txt @@ -1,7 +1,7 @@ add_qtc_executable(iostool DESTINATION ${IDE_LIBEXEC_PATH}/ios DEPENDS - Qt5::Gui + Qt5::Core Qt5::Xml Qt5::Network ${FWCoreFoundation} diff --git a/src/tools/iostool/gdbrunner.cpp b/src/tools/iostool/gdbrunner.cpp index 4f4f110c125..9c473ea2297 100644 --- a/src/tools/iostool/gdbrunner.cpp +++ b/src/tools/iostool/gdbrunner.cpp @@ -46,20 +46,20 @@ void GdbRunner::run() { { QMutexLocker l(&m_iosTool->m_xmlMutex); - if (!m_iosTool->splitAppOutput) { - m_iosTool->out.writeStartElement(QLatin1String("app_output")); - m_iosTool->inAppOutput = true; + if (!m_iosTool->m_splitAppOutput) { + m_iosTool->m_xmlWriter.writeStartElement(QLatin1String("app_output")); + m_iosTool->m_inAppOutput = true; } - m_iosTool->outFile.flush(); + m_iosTool->m_outputFile.flush(); } Ios::IosDeviceManager::instance()->processGdbServer(m_conn); { QMutexLocker l(&m_iosTool->m_xmlMutex); - if (!m_iosTool->splitAppOutput) { - m_iosTool->inAppOutput = false; - m_iosTool->out.writeEndElement(); + if (!m_iosTool->m_splitAppOutput) { + m_iosTool->m_inAppOutput = false; + m_iosTool->m_xmlWriter.writeEndElement(); } - m_iosTool->outFile.flush(); + m_iosTool->m_outputFile.flush(); } MobileDeviceLib::instance().serviceConnectionInvalidate(m_conn); m_conn = nullptr; diff --git a/src/tools/iostool/iosdevicemanager.cpp b/src/tools/iostool/iosdevicemanager.cpp index 781420beeb0..ffa7e5f401c 100644 --- a/src/tools/iostool/iosdevicemanager.cpp +++ b/src/tools/iostool/iosdevicemanager.cpp @@ -46,17 +46,13 @@ #include -#include #include - -static const bool debugGdbServer = false; -static const bool debugAll = false; -static const bool verbose = true; -static const bool noWifi = true; +#include namespace { - Q_LOGGING_CATEGORY(loggingCategory, "qtc.iostool.iosdevicemanager", QtWarningMsg) -} +Q_LOGGING_CATEGORY(loggingCategory, "qtc.iostool.iosdevicemanager", QtWarningMsg) +Q_LOGGING_CATEGORY(loggingCategoryGdb, "qtc.iostool.iosdevicemanager", QtWarningMsg) +} // namespace // ------- MobileDeviceLib interface -------- namespace { @@ -64,15 +60,9 @@ namespace { #ifndef MOBILE_DEV_DIRECT_LINK /* Messages passed to device notification callbacks: passed as part of * AMDeviceNotificationCallbackInfo. */ -enum ADNCI_MSG { - ADNCI_MSG_CONNECTED = 1, - ADNCI_MSG_DISCONNECTED = 2, - ADNCI_MSG_UNSUBSCRIBED = 3 -}; +enum ADNCI_MSG { ADNCI_MSG_CONNECTED = 1, ADNCI_MSG_DISCONNECTED = 2, ADNCI_MSG_UNSUBSCRIBED = 3 }; #endif - - } // anonymous namespace namespace Ios { @@ -82,7 +72,6 @@ static const am_res_t kAMDMobileImageMounterImageMountFailed = 0xe8000076; static const QString DebugServiceName = "com.apple.debugserver"; static const QString DebugSecureServiceName = "com.apple.debugserver.DVTSecureSocketProxy"; - static QString mobileDeviceErrorString(am_res_t code) { QString s = QStringLiteral("Unknown error (0x%08x)").arg(code); @@ -90,25 +79,24 @@ static QString mobileDeviceErrorString(am_res_t code) MobileDeviceLib &mLib = MobileDeviceLib::instance(); // AMDErrors, 0x0, 0xe8000001-0xe80000db if (char *ptr = mLib.errorString(code)) { - CFStringRef key = QString::fromLatin1(ptr).toCFString(); + const CFString_t key = CFString_t(QString::fromLatin1(ptr).toCFString()); - CFURLRef url = QUrl::fromLocalFile( - QStringLiteral("/System/Library/PrivateFrameworks/MobileDevice.framework")).toCFURL(); - CFBundleRef mobileDeviceBundle = CFBundleCreate(kCFAllocatorDefault, url); - CFRelease(url); + const CFUrl_t url( + QUrl::fromLocalFile( + QStringLiteral("/System/Library/PrivateFrameworks/MobileDevice.framework")) + .toCFURL()); + const CFBundle_t mobileDeviceBundle(CFBundleCreate(kCFAllocatorDefault, url.get())); if (mobileDeviceBundle) { - CFStringRef str = CFCopyLocalizedStringFromTableInBundle(key, CFSTR("Localizable"), - mobileDeviceBundle, nil); - s = QString::fromCFString(str); - CFRelease(str); + const CFString_t str(CFCopyLocalizedStringFromTableInBundle(key.get(), + CFSTR("Localizable"), + mobileDeviceBundle.get(), + nil)); + s = QString::fromCFString(str.get()); } - - CFRelease(key); - } else if (CFStringRef str = mLib.misErrorStringForErrorCode(code)) { + } else if (const CFString_t str = CFString_t(mLib.misErrorStringForErrorCode(code))) { // MIS errors, 0xe8008001-0xe800801e - s = QString::fromCFString(str); - CFRelease(str); + s = QString::fromCFString(str.get()); } return s; @@ -149,7 +137,8 @@ static bool findXcodePath(QString *xcodePath) * Returns \c true if \e DeveloperDiskImage.dmg is found, otherwise returns \c false. The absolute * path to the \e DeveloperDiskImage.dmg is enumerated in \a path. */ -static bool findDeveloperDiskImage(const QString &versionStr, const QString &buildStr, +static bool findDeveloperDiskImage(const QString &versionStr, + const QString &buildStr, QString *path = nullptr) { const QVersionNumber deviceVersion = QVersionNumber::fromString(versionStr); @@ -158,8 +147,7 @@ static bool findDeveloperDiskImage(const QString &versionStr, const QString &bui QString xcodePath; if (!findXcodePath(&xcodePath)) { - if (debugAll) - qDebug() << "Error getting xcode installation path."; + qCDebug(loggingCategory) << "Error getting xcode installation path."; return false; } @@ -198,10 +186,11 @@ static bool findDeveloperDiskImage(const QString &versionStr, const QString &bui return false; // Sort device support directories. - std::sort(deviceSupportDirs.begin(), deviceSupportDirs.end(), + std::sort(deviceSupportDirs.begin(), + deviceSupportDirs.end(), [compareVersion](const QFileInfo &a, const QFileInfo &b) { - return compareVersion(a.fileName(), b.fileName()); - }); + return compareVersion(a.fileName(), b.fileName()); + }); if (path) *path = QString("%1/DeveloperDiskImage.dmg").arg(deviceSupportDirs[0].absoluteFilePath()); @@ -210,10 +199,10 @@ static bool findDeveloperDiskImage(const QString &versionStr, const QString &bui bool disable_ssl(ServiceConnRef ref) { - typedef void (*SSL_free_t)(void*); + typedef void (*SSL_free_t)(void *); static SSL_free_t SSL_free = nullptr; if (!SSL_free) - SSL_free = (SSL_free_t)dlsym(RTLD_DEFAULT, "SSL_free"); + SSL_free = (SSL_free_t) dlsym(RTLD_DEFAULT, "SSL_free"); if (!SSL_free) return false; SSL_free(ref->sslContext); @@ -225,7 +214,8 @@ extern "C" { typedef void (*DeviceAvailableCallback)(QString deviceId, AMDeviceRef, void *userData); } -class PendingDeviceLookup { +class PendingDeviceLookup +{ public: QTimer timer; DeviceAvailableCallback callback; @@ -239,9 +229,7 @@ public: explicit CommandSession(const QString &deviceId); void internalDeviceAvailableCallback(QString deviceId, AMDeviceRef device); - virtual void deviceCallbackReturned() { } - virtual am_res_t appTransferCallback(CFDictionaryRef) { return 0; } - virtual am_res_t appInstallCallback(CFDictionaryRef) { return 0; } + virtual void deviceCallbackReturned() {} virtual void reportProgress(CFDictionaryRef dict); virtual void reportProgress2(int progress, const QString &status); virtual QString commandName(); @@ -276,10 +264,11 @@ private: // ------- IosManagerPrivate interface -------- -class IosDeviceManagerPrivate { +class IosDeviceManagerPrivate +{ public: static IosDeviceManagerPrivate *instance(); - explicit IosDeviceManagerPrivate (IosDeviceManager *q); + explicit IosDeviceManagerPrivate(IosDeviceManager *q); bool watchDevices(); void requestAppOp(const QString &bundlePath, const QStringList &extraArgs, @@ -295,15 +284,26 @@ public: void removeDevice(AMDeviceRef device); void checkPendingLookups(); MobileDeviceLib *lib(); - void didTransferApp(const QString &bundlePath, const QString &deviceId, + void didTransferApp(const QString &bundlePath, + const QString &deviceId, Ios::IosDeviceManager::OpStatus status); - void didStartApp(const QString &bundlePath, const QString &deviceId, - Ios::IosDeviceManager::OpStatus status, ServiceConnRef conn, int gdbFd, DeviceSession *deviceSession); - void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress, + void didStartApp(const QString &bundlePath, + const QString &deviceId, + Ios::IosDeviceManager::OpStatus status, + ServiceConnRef conn, + int gdbFd, + DeviceSession *deviceSession); + void isTransferringApp(const QString &bundlePath, + const QString &deviceId, + int progress, const QString &info); - void deviceWithId(QString deviceId, int timeout, DeviceAvailableCallback callback, void *userData); + void deviceWithId(QString deviceId, + int timeout, + DeviceAvailableCallback callback, + void *userData); int processGdbServer(ServiceConnRef conn); void stopGdbServer(ServiceConnRef conn, int phase); + private: IosDeviceManager *q; QMutex m_sendMutex; @@ -312,7 +312,8 @@ private: AMDeviceNotificationRef m_notification; }; -class DevInfoSession: public CommandSession { +class DevInfoSession : public CommandSession +{ public: DevInfoSession(const QString &deviceId); @@ -324,7 +325,8 @@ public: const QString &fallback = QString()); }; -class AppOpSession: public CommandSession { +class AppOpSession : public CommandSession +{ public: QString bundlePath; QStringList extraArgs; @@ -342,45 +344,42 @@ public: bool installAppNew(); bool runApp(); int qmljsDebugPort() const override; - am_res_t appTransferCallback(CFDictionaryRef dict) override; - am_res_t appInstallCallback(CFDictionaryRef dict) override; void reportProgress2(int progress, const QString &status) override; QString appPathOnDevice(); QString appId(); QString commandName() override; }; -} +} // namespace Internal -DeviceSession::DeviceSession(const QString &deviceId) : - deviceId(deviceId) -{ -} +DeviceSession::DeviceSession(const QString &deviceId) + : deviceId(deviceId) +{} -DeviceSession::~DeviceSession() -{ -} +DeviceSession::~DeviceSession() {} // namespace Internal } // namespace Ios - +namespace Ios { namespace { // ------- callbacks -------- extern "C" void deviceNotificationCallback(Ios::AMDeviceNotificationCallbackInfo *info, void *user) { - if (info == 0) - Ios::Internal::IosDeviceManagerPrivate::instance()->addError(QLatin1String("null info in deviceNotificationCallback")); - if (debugAll) { - QDebug dbg=qDebug(); - dbg << "device_notification_callback("; - if (info) - dbg << " dev:" << info->_device << " msg:" << info->_message << " subscription:" << info->_subscription; - else - dbg << "*NULL*"; - dbg << "," << user << ")"; + if (!info) { + Ios::Internal::IosDeviceManagerPrivate::instance()->addError( + QLatin1String("null info in deviceNotificationCallback")); + qCDebug(loggingCategory) << "device_notification_callback(" + << "*NULL*" + << "," << user << ")"; + return; } + + qCDebug(loggingCategory) << "device_notification_callback(" + << " dev:" << info->_device << " msg:" << info->_message + << " subscription:" << info->_subscription << "," << user << ")"; + switch (info->_message) { case ADNCI_MSG_CONNECTED: Ios::Internal::IosDeviceManagerPrivate::instance()->addDevice(info->_device); @@ -391,59 +390,82 @@ extern "C" void deviceNotificationCallback(Ios::AMDeviceNotificationCallbackInfo case ADNCI_MSG_UNSUBSCRIBED: break; default: - Ios::Internal::IosDeviceManagerPrivate::instance()->addError(QLatin1String("unexpected notification message value ") - + QString::number(info->_message)); + Ios::Internal::IosDeviceManagerPrivate::instance()->addError( + QLatin1String("unexpected notification message value ") + + QString::number(info->_message)); } } -extern "C" void deviceAvailableSessionCallback(QString deviceId, Ios::AMDeviceRef device, void *userData) +extern "C" void deviceAvailableSessionCallback(QString deviceId, + Ios::AMDeviceRef device, + void *userData) { - if (debugAll) - qDebug() << "deviceAvailableSessionCallback" << QThread::currentThread(); - if (userData == 0) { - Ios::Internal::IosDeviceManagerPrivate::instance()->addError(QLatin1String("deviceAvailableSessionCallback called with null userData")); + qCDebug(loggingCategory) << "deviceAvailableSessionCallback" << QThread::currentThread(); + + if (!userData) { + Ios::Internal::IosDeviceManagerPrivate::instance()->addError( + QLatin1String("deviceAvailableSessionCallback called with null userData")); return; } Ios::Internal::CommandSession *session = static_cast(userData); session->internalDeviceAvailableCallback(deviceId, device); } -extern "C" Ios::am_res_t appTransferSessionCallback(CFDictionaryRef dict, void *userData) -{ - if (debugAll) { - qDebug() << "appTransferSessionCallback" << QThread::currentThread(); - CFShow(dict); - } - if (userData == 0) { - Ios::Internal::IosDeviceManagerPrivate::instance()->addError(QLatin1String("appTransferSessionCallback called with null userData")); - return 0; // return -1? - } - Ios::Internal::CommandSession *session = static_cast(userData); - return session->appTransferCallback(dict); -} - - extern "C" mach_error_t appSecureTransferSessionCallback(CFDictionaryRef dict, int arg) { Q_UNUSED(arg) - CFStringRef cfStatus = reinterpret_cast(CFDictionaryGetValue(dict, CFSTR("Status"))); - const QString status = QString::fromCFString(cfStatus); - quint32 percent = 0; - CFNumberRef cfProgress; - if (CFDictionaryGetValueIfPresent(dict, CFSTR("PercentComplete"), reinterpret_cast(&cfProgress))) { - if (cfProgress && CFGetTypeID(cfProgress) == CFNumberGetTypeID()) - CFNumberGetValue(cfProgress, kCFNumberSInt32Type, reinterpret_cast(&percent)); - } + const CFString_t cfStatus( + reinterpret_cast(CFDictionaryGetValue(dict, CFSTR("Status")))); + const QString status = QString::fromCFString(cfStatus.get()); - QString path; - if (status == "CopyingFile") { - CFStringRef cfPath = reinterpret_cast(CFDictionaryGetValue(dict, CFSTR("Path"))); - path = QString::fromCFString(cfPath); - } + if (loggingCategory().isInfoEnabled()) { + quint32 percent = 0; + CFNumberRef cfProgress; + if (CFDictionaryGetValueIfPresent(dict, + CFSTR("PercentComplete"), + reinterpret_cast(&cfProgress))) { + if (cfProgress && CFGetTypeID(cfProgress) == CFNumberGetTypeID()) + CFNumberGetValue(cfProgress, + kCFNumberSInt32Type, + reinterpret_cast(&percent)); + } - if (debugAll) { - qDebug() << "["<(CFDictionaryGetValue(dict, CFSTR("Path")))); + path = QString::fromCFString(cfPath.get()); + } + + static QElapsedTimer pathTimer; + static QElapsedTimer statusTimer; + static quint32 lastPercent = percent; + static QString oldPath = path; + static QString oldStatus = ""; + + if (oldPath != path) { + if (!oldPath.isEmpty()) { + qCInfo(loggingCategory) + << oldStatus << oldPath << "took" << pathTimer.elapsed() << "ms"; + } + oldPath = path; + pathTimer.restart(); + } + + if (oldStatus != status) { + if (!oldStatus.isEmpty()) { + qCInfo(loggingCategory) << oldStatus << "took" << statusTimer.elapsed() << "ms"; + } + oldStatus = status; + statusTimer.restart(); + } + + if (lastPercent != percent || oldPath != path) { + qCInfo(loggingCategory).nospace() + << "[ " << percent << "% ] " << qPrintable(status) << ": " << path; + lastPercent = percent; + } } else { static QString oldStatus; if (oldStatus != status) { @@ -451,26 +473,12 @@ extern "C" mach_error_t appSecureTransferSessionCallback(CFDictionaryRef dict, i oldStatus = status; } } - return 0; -} -extern "C" Ios::am_res_t appInstallSessionCallback(CFDictionaryRef dict, void *userData) -{ - if (debugAll) { - qDebug() << "appInstallSessionCallback" << QThread::currentThread(); - CFShow(dict); - } - if (userData == 0) { - Ios::Internal::IosDeviceManagerPrivate::instance()->addError(QLatin1String("appInstallSessionCallback called with null userData")); - return 0; // return -1? - } - Ios::Internal::CommandSession *session = static_cast(userData); - return session->appInstallCallback(dict); + return 0; } } // anonymous namespace -namespace Ios { namespace Internal { // ------- IosManagerPrivate implementation -------- @@ -480,19 +488,26 @@ IosDeviceManagerPrivate *IosDeviceManagerPrivate::instance() return IosDeviceManager::instance()->d; } -IosDeviceManagerPrivate::IosDeviceManagerPrivate (IosDeviceManager *q) : q(q), m_notification(0) { } +IosDeviceManagerPrivate::IosDeviceManagerPrivate(IosDeviceManager *q) + : q(q) + , m_notification(0) +{} bool IosDeviceManagerPrivate::watchDevices() { MobileDeviceLib &mLib = MobileDeviceLib::instance(); - am_res_t e = mLib.deviceNotificationSubscribe(&deviceNotificationCallback, 0, 0, - 0, &m_notification); - if (e != 0) { + am_res_t error = mLib.deviceNotificationSubscribe(&deviceNotificationCallback, + 0, + 0, + 0, + &m_notification); + if (error) { addError(QLatin1String("AMDeviceNotificationSubscribe failed")); return false; } - if (debugAll) - qDebug() << "AMDeviceNotificationSubscribe successful, m_notificationIter:" << m_notification << QThread::currentThread(); + + qCDebug(loggingCategory) << "AMDeviceNotificationSubscribe successful, m_notificationIter:" + << m_notification << QThread::currentThread(); return true; } @@ -522,18 +537,17 @@ QStringList IosDeviceManagerPrivate::errors() void IosDeviceManagerPrivate::addError(QString errorMsg) { - if (debugAll) - qDebug() << "IosManagerPrivate ERROR: " << errorMsg; + qCDebug(loggingCategory) << "IosManagerPrivate ERROR: " << errorMsg; emit q->errorMsg(errorMsg); } QString IosDeviceManagerPrivate::deviceId(AMDeviceRef device) { MobileDeviceLib &mLib = MobileDeviceLib::instance(); - CFStringRef s = mLib.deviceCopyDeviceIdentifier(device); + const CFString_t s(mLib.deviceCopyDeviceIdentifier(device)); // remove dashes as a hotfix for QTCREATORBUG-21291 - const auto id = QString::fromCFString(s).remove('-'); - if (s) CFRelease(s); + const auto id = QString::fromCFString(s.get()).remove('-'); + return id; } @@ -543,22 +557,21 @@ void IosDeviceManagerPrivate::addDevice(AMDeviceRef device) CFRetain(device); MobileDeviceLib &mLib = MobileDeviceLib::instance(); - DeviceInterfaceType interfaceType = static_cast(mLib.deviceGetInterfaceType(device)); + DeviceInterfaceType interfaceType = static_cast( + mLib.deviceGetInterfaceType(device)); if (interfaceType == DeviceInterfaceType::UNKNOWN) { - if (debugAll) - qDebug() << "Skipping device." << devId << "Interface type: Unknown."; + qCDebug(loggingCategory) << "Skipping device." << devId << "Interface type: Unknown."; return; } // Skip the wifi connections as debugging over wifi is not supported. - if (noWifi && interfaceType == DeviceInterfaceType::WIFI) { - if (debugAll) - qDebug() << "Skipping device." << devId << "Interface type: WIFI. Debugging over WIFI is not supported."; + if (interfaceType == DeviceInterfaceType::WIFI) { + qCInfo(loggingCategory) << "Skipping device." << devId + << "Interface type: WIFI. Debugging over WIFI is not supported."; return; } - if (debugAll) - qDebug() << "addDevice " << devId; + qCDebug(loggingCategory) << "addDevice " << devId; if (m_devices.contains(devId)) { if (m_devices.value(devId) == device) { addError(QLatin1String("double add of device ") + devId); @@ -575,7 +588,7 @@ void IosDeviceManagerPrivate::addDevice(AMDeviceRef device) devices << m_pendingLookups.values(QString()); m_pendingLookups.remove(QString()); for (PendingDeviceLookup *devLookup : qAsConst(devices)) { - if (debugAll) qDebug() << "found pending op"; + qCDebug(loggingCategory) << "found pending op"; devLookup->timer.stop(); devLookup->callback(devId, device, devLookup->userData); delete devLookup; @@ -586,8 +599,7 @@ void IosDeviceManagerPrivate::addDevice(AMDeviceRef device) void IosDeviceManagerPrivate::removeDevice(AMDeviceRef device) { const QString devId = deviceId(device); - if (debugAll) - qDebug() << "removeDevice " << devId; + qCDebug(loggingCategory) << "removeDevice " << devId; if (m_devices.contains(devId)) { if (m_devices.value(devId) == device) { CFRelease(device); @@ -616,40 +628,50 @@ void IosDeviceManagerPrivate::checkPendingLookups() } } -void IosDeviceManagerPrivate::didTransferApp(const QString &bundlePath, const QString &deviceId, - IosDeviceManager::OpStatus status) +void IosDeviceManagerPrivate::didTransferApp(const QString &bundlePath, + const QString &deviceId, + IosDeviceManager::OpStatus status) { emit IosDeviceManagerPrivate::instance()->q->didTransferApp(bundlePath, deviceId, status); } -void IosDeviceManagerPrivate::didStartApp(const QString &bundlePath, const QString &deviceId, - IosDeviceManager::OpStatus status, ServiceConnRef conn, - int gdbFd, DeviceSession *deviceSession) +void IosDeviceManagerPrivate::didStartApp(const QString &bundlePath, + const QString &deviceId, + IosDeviceManager::OpStatus status, + ServiceConnRef conn, + int gdbFd, + DeviceSession *deviceSession) { - emit IosDeviceManagerPrivate::instance()->q->didStartApp(bundlePath, deviceId, status, conn, - gdbFd, deviceSession); + emit IosDeviceManagerPrivate::instance() + ->q->didStartApp(bundlePath, deviceId, status, conn, gdbFd, deviceSession); } -void IosDeviceManagerPrivate::isTransferringApp(const QString &bundlePath, const QString &deviceId, - int progress, const QString &info) +void IosDeviceManagerPrivate::isTransferringApp(const QString &bundlePath, + const QString &deviceId, + int progress, + const QString &info) { - emit IosDeviceManagerPrivate::instance()->q->isTransferringApp(bundlePath, deviceId, progress, info); + emit IosDeviceManagerPrivate::instance()->q->isTransferringApp(bundlePath, + deviceId, + progress, + info); } -void IosDeviceManagerPrivate::deviceWithId(QString deviceId, int timeout, - DeviceAvailableCallback callback, - void *userData) +void IosDeviceManagerPrivate::deviceWithId(QString deviceId, + int timeout, + DeviceAvailableCallback callback, + void *userData) { if (!m_notification) { - qDebug() << "null notification!!"; + qCWarning(loggingCategory) << "null notification!!"; /*if (!watchDevices()) { callback(deviceId, 0, userData); return; }*/ } if (deviceId.isEmpty() && !m_devices.isEmpty()) { - QHash::iterator i = m_devices.begin(); - callback(i.key(), i.value() , userData); + QHash::iterator i = m_devices.begin(); + callback(i.key(), i.value(), userData); return; } if (m_devices.contains(deviceId)) { @@ -665,7 +687,10 @@ void IosDeviceManagerPrivate::deviceWithId(QString deviceId, int timeout, pendingLookup->userData = userData; pendingLookup->timer.setSingleShot(true); pendingLookup->timer.setInterval(timeout); - QObject::connect(&(pendingLookup->timer), &QTimer::timeout, q, &IosDeviceManager::checkPendingLookups); + QObject::connect(&(pendingLookup->timer), + &QTimer::timeout, + q, + &IosDeviceManager::checkPendingLookups); m_pendingLookups.insert(deviceId, pendingLookup); pendingLookup->timer.start(); } @@ -696,51 +721,50 @@ int IosDeviceManagerPrivate::processGdbServer(ServiceConnRef conn) case 'S': if (repl.size() < 3) { addError(QString::fromLatin1("invalid S signal message %1") - .arg(QString::fromLatin1(repl.constData(), repl.size()))); + .arg(QString::fromLatin1(repl.constData(), repl.size()))); state = PROTOCOL_ERROR; } else { - signal = QByteArray::fromHex(repl.mid(1,2)).at(0); - addError(QString::fromLatin1("program received signal %1") - .arg(signal)); + signal = QByteArray::fromHex(repl.mid(1, 2)).at(0); + addError(QString::fromLatin1("program received signal %1").arg(signal)); state = STOP_FOR_SIGNAL; } break; case 'T': if (repl.size() < 3) { addError(QString::fromLatin1("invalid T signal message %1") - .arg(QString::fromLatin1(repl.constData(), repl.size()))); + .arg(QString::fromLatin1(repl.constData(), repl.size()))); state = PROTOCOL_ERROR; } else { - signal = QByteArray::fromHex(repl.mid(1,2)).at(0); + signal = QByteArray::fromHex(repl.mid(1, 2)).at(0); addError(QString::fromLatin1("program received signal %1, %2") - .arg(signal) - .arg(QString::fromLatin1(repl.mid(3,repl.size()-3)))); + .arg(signal) + .arg(QString::fromLatin1(repl.mid(3, repl.size() - 3)))); state = STOP_FOR_SIGNAL; } break; case 'W': if (repl.size() < 3) { addError(QString::fromLatin1("invalid W signal message %1") - .arg(QString::fromLatin1(repl.constData(), repl.size()))); + .arg(QString::fromLatin1(repl.constData(), repl.size()))); state = PROTOCOL_ERROR; } else { - int exitCode = QByteArray::fromHex(repl.mid(1,2)).at(0); + int exitCode = QByteArray::fromHex(repl.mid(1, 2)).at(0); addError(QString::fromLatin1("exited with exit code %1, %2") - .arg(exitCode) - .arg(QString::fromLatin1(repl.mid(3,repl.size()-3)))); + .arg(exitCode) + .arg(QString::fromLatin1(repl.mid(3, repl.size() - 3)))); state = INFERIOR_EXITED; } break; case 'X': if (repl.size() < 3) { addError(QString::fromLatin1("invalid X signal message %1") - .arg(QString::fromLatin1(repl.constData(), repl.size()))); + .arg(QString::fromLatin1(repl.constData(), repl.size()))); state = PROTOCOL_ERROR; } else { - int exitCode = QByteArray::fromHex(repl.mid(1,2)).at(0); + int exitCode = QByteArray::fromHex(repl.mid(1, 2)).at(0); addError(QString::fromLatin1("exited due to signal %1, %2") - .arg(exitCode) - .arg(QString::fromLatin1(repl.mid(3,repl.size()-3)))); + .arg(exitCode) + .arg(QString::fromLatin1(repl.mid(3, repl.size() - 3)))); state = INFERIOR_EXITED; } break; @@ -754,9 +778,9 @@ int IosDeviceManagerPrivate::processGdbServer(ServiceConnRef conn) state = PROTOCOL_UNHANDLED; } if (state == STOP_FOR_SIGNAL) { - QList okSig = QList() << SIGCHLD << SIGCONT << SIGALRM << SIGURG - << SIGUSR1 << SIGUSR2 << SIGPIPE - << SIGPROF << SIGWINCH << SIGINFO; + QList okSig = QList() + << SIGCHLD << SIGCONT << SIGALRM << SIGURG << SIGUSR1 << SIGUSR2 + << SIGPIPE << SIGPROF << SIGWINCH << SIGINFO; if (signal == 9) { break; } else if (!okSig.contains(signal) && --maxSignal < 0) { @@ -799,11 +823,15 @@ void IosDeviceManagerPrivate::stopGdbServer(ServiceConnRef conn, int phase) // ------- ConnectSession implementation -------- -CommandSession::CommandSession(const QString &deviceId) : DeviceSession(deviceId), device(0), - progressBase(0), unexpectedChars(0), aknowledge(true) -{ } +CommandSession::CommandSession(const QString &deviceId) + : DeviceSession(deviceId) + , device(0) + , progressBase(0) + , unexpectedChars(0) + , aknowledge(true) +{} -CommandSession::~CommandSession() { } +CommandSession::~CommandSession() {} bool CommandSession::connectDevice() { @@ -813,24 +841,34 @@ bool CommandSession::connectDevice() MobileDeviceLib &mLib = MobileDeviceLib::instance(); if (am_res_t error1 = mLib.deviceConnect(device)) { addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceConnect returned %2 (0x%3)") - .arg(deviceId).arg(mobileDeviceErrorString(error1)).arg(error1)); + .arg(deviceId) + .arg(mobileDeviceErrorString(error1)) + .arg(error1)); return false; } if (mLib.deviceIsPaired(device) == 0) { // not paired if (am_res_t error = mLib.devicePair(device)) { addError(QString::fromLatin1("connectDevice %1 failed, AMDevicePair returned %2 (0x%3)") - .arg(deviceId).arg(mobileDeviceErrorString(error)).arg(error)); + .arg(deviceId) + .arg(mobileDeviceErrorString(error)) + .arg(error)); return false; } } if (am_res_t error2 = mLib.deviceValidatePairing(device)) { - addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceValidatePairing returned %2 (0x%3)") - .arg(deviceId).arg(mobileDeviceErrorString(error2)).arg(error2)); + addError(QString::fromLatin1( + "connectDevice %1 failed, AMDeviceValidatePairing returned %2 (0x%3)") + .arg(deviceId) + .arg(mobileDeviceErrorString(error2)) + .arg(error2)); return false; } if (am_res_t error3 = mLib.deviceStartSession(device)) { - addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceStartSession returned %2 (0x%3)") - .arg(deviceId).arg(mobileDeviceErrorString(error3)).arg(error3)); + addError( + QString::fromLatin1("connectDevice %1 failed, AMDeviceStartSession returned %2 (0x%3)") + .arg(deviceId) + .arg(mobileDeviceErrorString(error3)) + .arg(error3)); return false; } return true; @@ -840,13 +878,19 @@ bool CommandSession::disconnectDevice() { MobileDeviceLib &mLib = MobileDeviceLib::instance(); if (am_res_t error = mLib.deviceStopSession(device)) { - addError(QString::fromLatin1("stopSession %1 failed, AMDeviceStopSession returned %2 (0x%3)") - .arg(deviceId).arg(mobileDeviceErrorString(error)).arg(error)); + addError( + QString::fromLatin1("stopSession %1 failed, AMDeviceStopSession returned %2 (0x%3)") + .arg(deviceId) + .arg(mobileDeviceErrorString(error)) + .arg(error)); return false; } if (am_res_t error = mLib.deviceDisconnect(device)) { - addError(QString::fromLatin1("disconnectDevice %1 failed, AMDeviceDisconnect returned %2 (0x%3)") - .arg(deviceId).arg(mobileDeviceErrorString(error)).arg(error)); + addError( + QString::fromLatin1("disconnectDevice %1 failed, AMDeviceDisconnect returned %2 (0x%3)") + .arg(deviceId) + .arg(mobileDeviceErrorString(error)) + .arg(error)); return false; } return true; @@ -858,23 +902,31 @@ bool CommandSession::startServiceSecure(const QString &serviceName, ServiceConnR // Connect device. AMDeviceConnect + AMDeviceIsPaired + AMDeviceValidatePairing + AMDeviceStartSession if (connectDevice()) { - CFStringRef cfsService = serviceName.toCFString(); + const CFString_t cfsService(serviceName.toCFString()); MobileDeviceLib &mLib = MobileDeviceLib::instance(); - if (am_res_t error = mLib.deviceSecureStartService(device, cfsService, &conn)) { - addError(QString::fromLatin1("Starting(Secure) service \"%1\" on device %2 failed, AMDeviceStartSecureService returned %3 (0x%4)") - .arg(serviceName).arg(deviceId).arg(mobileDeviceErrorString(error)).arg(QString::number(error, 16))); + if (am_res_t error = mLib.deviceSecureStartService(device, cfsService.get(), &conn)) { + addError(QString::fromLatin1("Starting(Secure) service \"%1\" on device %2 failed, " + "AMDeviceStartSecureService returned %3 (0x%4)") + .arg(serviceName) + .arg(deviceId) + .arg(mobileDeviceErrorString(error)) + .arg(QString::number(error, 16))); success = false; } else { if (!conn) { addError(QString("Starting(Secure) service \"%1\" on device %2 failed." - "Invalid service connection").arg(serviceName).arg(deviceId)); + "Invalid service connection") + .arg(serviceName) + .arg(deviceId)); } } disconnectDevice(); - CFRelease(cfsService); } else { - addError(QString::fromLatin1("Starting(Secure) service \"%1\" on device %2 failed. Cannot connect to device.") - .arg(serviceName).arg(deviceId)); + addError( + QString::fromLatin1( + "Starting(Secure) service \"%1\" on device %2 failed. Cannot connect to device.") + .arg(serviceName) + .arg(deviceId)); success = false; } return success; @@ -891,9 +943,14 @@ bool CommandSession::connectToPort(quint16 port, ServiceSocket *fd) return false; MobileDeviceLib &mLib = MobileDeviceLib::instance(); - if (am_res_t error = mLib.connectByPort(mLib.deviceGetConnectionID(device), htons(port), &fileDescriptor)) { - addError(QString::fromLatin1("connectByPort on device %1 port %2 failed, AMDeviceStartService returned %3") - .arg(deviceId).arg(port).arg(error)); + if (am_res_t error = mLib.connectByPort(mLib.deviceGetConnectionID(device), + htons(port), + &fileDescriptor)) { + addError(QString::fromLatin1( + "connectByPort on device %1 port %2 failed, AMDeviceStartService returned %3") + .arg(deviceId) + .arg(port) + .arg(error)); failure = true; *fd = -1; } else { @@ -916,14 +973,15 @@ void CommandSession::stopService(ServiceSocket fd) void CommandSession::startDeviceLookup(int timeout) { - IosDeviceManagerPrivate::instance()->deviceWithId(deviceId, timeout, - &deviceAvailableSessionCallback, this); + IosDeviceManagerPrivate::instance()->deviceWithId(deviceId, + timeout, + &deviceAvailableSessionCallback, + this); } void CommandSession::addError(const QString &msg) { - if (verbose) - qDebug() << "CommandSession ERROR: " << msg; + qCCritical(loggingCategory) << "CommandSession ERROR:" << msg; IosDeviceManagerPrivate::instance()->addError(commandName() + msg); } @@ -931,11 +989,11 @@ bool CommandSession::writeAll(ServiceSocket fd, const char *cmd, qptrdiff len) { if (len == -1) len = strlen(cmd); - if (debugGdbServer) { - QByteArray cmdBA(cmd,len); - qDebug() << "writeAll(" << fd << "," << QString::fromLocal8Bit(cmdBA.constData(), cmdBA.size()) - << " (" << cmdBA.toHex() << "))"; - } + + qCDebug(loggingCategoryGdb) << "writeAll(" << fd << "," + << QString::fromLocal8Bit(QByteArray{cmd, (int)len}) << " (" + << QByteArray{cmd, (int)len}.toHex() << "))"; + qptrdiff i = 0; int maxRetry = 10; while (i < len) { @@ -945,7 +1003,7 @@ bool CommandSession::writeAll(ServiceSocket fd, const char *cmd, qptrdiff len) if (nWritten == -1 && errno != 0 && errno != EINTR) { char buf[256]; if (!strerror_r(errno, buf, sizeof(buf))) { - buf[sizeof(buf)-1] = 0; + buf[sizeof(buf) - 1] = 0; addError(QString::fromLocal8Bit(buf)); } else { addError(QLatin1String("Unknown writeAll error")); @@ -967,11 +1025,13 @@ bool CommandSession::writeAll(ServiceSocket fd, const char *cmd, qptrdiff len) void mountCallback(CFDictionaryRef dict, int arg) { Q_UNUSED(arg) - CFStringRef cfStatus = reinterpret_cast(CFDictionaryGetValue(dict, CFSTR("Status"))); - qDebug() << "Mounting dev Image :"<( + CFDictionaryGetValue(dict, CFSTR("Status")))); } -bool CommandSession::mountDeveloperDiskImage() { +bool CommandSession::mountDeveloperDiskImage() +{ bool success = false; QString imagePath; QString signaturePath; @@ -983,34 +1043,47 @@ bool CommandSession::mountDeveloperDiskImage() { sigFile.close(); CFDataRef sig_data = signatureData.toRawCFData(); - CFTypeRef keys[] = { CFSTR("ImageSignature"), CFSTR("ImageType") }; - CFTypeRef values[] = { sig_data, CFSTR("Developer") }; - CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, - 2, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + CFTypeRef keys[] = {CFSTR("ImageSignature"), CFSTR("ImageType")}; + CFTypeRef values[] = {sig_data, CFSTR("Developer")}; + CFDictionary_t options(CFDictionaryCreate(NULL, + (const void **) &keys, + (const void **) &values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); if (connectDevice()) { - CFStringRef cfImgPath = imagePath.toCFString(); + const CFString_t cfImgPath(imagePath.toCFString()); MobileDeviceLib &mLib = MobileDeviceLib::instance(); - am_res_t result = mLib.deviceMountImage(device, cfImgPath, options, &mountCallback, 0); - if (result == 0 || result == kAMDMobileImageMounterImageMountFailed) { + am_res_t result = mLib.deviceMountImage(device, + cfImgPath.get(), + options.get(), + &mountCallback, + 0); + if (result == 0 || result == kAMDMobileImageMounterImageMountFailed) { // Mounting succeeded or developer image already installed success = true; } else { - addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed, AMDeviceMountImage returned %2 (0x%3)") - .arg(imagePath).arg(mobileDeviceErrorString(result)).arg(QString::number(result, 16))); + addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed, " + "AMDeviceMountImage returned %2 (0x%3)") + .arg(imagePath) + .arg(mobileDeviceErrorString(result)) + .arg(QString::number(result, 16))); } - CFRelease(cfImgPath); disconnectDevice(); } else - addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed. Cannot connect to device \"%2\".") - .arg(imagePath).arg(deviceId)); + addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed. Cannot " + "connect to device \"%2\".") + .arg(imagePath) + .arg(deviceId)); } else { - addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed. Unable to open disk image.") - .arg(imagePath)); + addError(QString::fromLatin1( + "Mount Developer Disk Image \"%1\" failed. Unable to open disk image.") + .arg(imagePath)); } } else { - addError(QString::fromLatin1("Mount Developer Disk Image failed. Unable to fetch developer disk image path.")); + addError(QString::fromLatin1( + "Mount Developer Disk Image failed. Unable to fetch developer disk image path.")); } return success; } @@ -1030,7 +1103,7 @@ bool CommandSession::sendGdbCommand(ServiceConnRef conn, const char *cmd, qptrdi char buf[3]; buf[0] = '#'; const char *hex = "0123456789abcdef"; - buf[1] = hex[(checkSum >> 4) & 0xF]; + buf[1] = hex[(checkSum >> 4) & 0xF]; buf[2] = hex[checkSum & 0xF]; if (!failure) failure = mLib.serviceConnectionSend(conn, buf, 3) == 0; @@ -1044,7 +1117,7 @@ bool CommandSession::checkRead(qptrdiff nRead, int &maxRetry) if ((nRead < 0 || nRead > 4) && errno != 0 && errno != EINTR) { char buf[256]; if (!strerror_r(errno, buf, sizeof(buf))) { - buf[sizeof(buf)-1] = 0; + buf[sizeof(buf) - 1] = 0; addError(QString::fromLocal8Bit(buf)); } else { addError(QLatin1String("Unknown writeAll error")); @@ -1070,10 +1143,11 @@ int CommandSession::handleChar(ServiceConnRef conn, QByteArray &res, char c, int if (c != '+' && c != '-') { if (unexpectedChars < 10) { addError(QString::fromLatin1("unexpected char %1 in readGdbReply looking for $") - .arg(QChar::fromLatin1(c))); + .arg(QChar::fromLatin1(c))); ++unexpectedChars; } else if (unexpectedChars == 10) { - addError(QString::fromLatin1("hit maximum number of unexpected chars, ignoring them in readGdbReply looking for $")); + addError(QString::fromLatin1("hit maximum number of unexpected chars, ignoring " + "them in readGdbReply looking for $")); ++unexpectedChars; } } @@ -1089,10 +1163,11 @@ int CommandSession::handleChar(ServiceConnRef conn, QByteArray &res, char c, int if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F')) { if (unexpectedChars < 15) { addError(QString::fromLatin1("unexpected char %1 in readGdbReply as checksum") - .arg(QChar::fromLatin1(c))); + .arg(QChar::fromLatin1(c))); ++unexpectedChars; } else if (unexpectedChars == 15) { - addError(QString::fromLatin1("hit maximum number of unexpected chars in checksum, ignoring them in readGdbReply")); + addError(QString::fromLatin1("hit maximum number of unexpected chars in checksum, " + "ignoring them in readGdbReply")); ++unexpectedChars; } } @@ -1125,11 +1200,11 @@ QByteArray CommandSession::readGdbReply(ServiceConnRef conn) qptrdiff nRead = mLib.serviceConnectionReceive(conn, buf, toRead); if (!checkRead(nRead, maxRetry)) return QByteArray(); - if (debugGdbServer) { - buf[nRead] = 0; - qDebug() << "gdbReply read " << buf; - } - for (qptrdiff i = 0; i< nRead; ++i) + + qCDebug(loggingCategoryGdb) + << "gdbReply read" << QString::fromLocal8Bit(QByteArray{buf, (int)nRead}); + + for (qptrdiff i = 0; i < nRead; ++i) status = handleChar(conn, res, buf[i], status); toRead = 4 - status; } @@ -1144,15 +1219,24 @@ void CommandSession::reportProgress(CFDictionaryRef dict) { QString status; CFStringRef cfStatus; - if (CFDictionaryGetValueIfPresent(dict, CFSTR("Status"), reinterpret_cast(&cfStatus))) { - if (cfStatus && CFGetTypeID(cfStatus) == CFStringGetTypeID()) + if (CFDictionaryGetValueIfPresent(dict, + CFSTR("Status"), + reinterpret_cast(&cfStatus))) { + if (cfStatus && CFGetTypeID(cfStatus) == CFStringGetTypeID()) { status = QString::fromCFString(cfStatus); + } } + CFRelease(cfStatus); + quint32 progress = 0; CFNumberRef cfProgress; - if (CFDictionaryGetValueIfPresent(dict, CFSTR("PercentComplete"), reinterpret_cast(&cfProgress))) { + if (CFDictionaryGetValueIfPresent(dict, + CFSTR("PercentComplete"), + reinterpret_cast(&cfProgress))) { if (cfProgress && CFGetTypeID(cfProgress) == CFNumberGetTypeID()) - CFNumberGetValue(cfProgress,kCFNumberSInt32Type, reinterpret_cast(&progress)); + CFNumberGetValue(cfProgress, + kCFNumberSInt32Type, + reinterpret_cast(&progress)); } reportProgress2(progressBase + progress, status); } @@ -1172,11 +1256,12 @@ bool CommandSession::expectGdbReply(ServiceConnRef conn, QByteArray expected) { QByteArray repl = readGdbReply(conn); if (repl != expected) { - addError(QString::fromLatin1("Unexpected reply: %1 (%2) vs %3 (%4)") - .arg(QString::fromLocal8Bit(repl.constData(), repl.size())) - .arg(QString::fromLatin1(repl.toHex().constData(), 2*repl.size())) - .arg(QString::fromLocal8Bit(expected.constData(), expected.size())) - .arg(QString::fromLocal8Bit(expected.toHex().constData(), 2*expected.size()))); + addError( + QString::fromLatin1("Unexpected reply: %1 (%2) vs %3 (%4)") + .arg(QString::fromLocal8Bit(repl.constData(), repl.size())) + .arg(QString::fromLatin1(repl.toHex().constData(), 2 * repl.size())) + .arg(QString::fromLocal8Bit(expected.constData(), expected.size())) + .arg(QString::fromLocal8Bit(expected.toHex().constData(), 2 * expected.size()))); return false; } return true; @@ -1191,24 +1276,23 @@ bool CommandSession::developerDiskImagePath(QString *path, QString *signaturePat { if (device && path && connectDevice()) { MobileDeviceLib &mLib = MobileDeviceLib::instance(); - CFPropertyListRef cfProductVersion = mLib.deviceCopyValue(device, 0, CFSTR("ProductVersion")); + const CFPropertyList_t cfProductVersion( + mLib.deviceCopyValue(device, 0, CFSTR("ProductVersion"))); QString versionString; - if (cfProductVersion && CFGetTypeID(cfProductVersion) == CFStringGetTypeID()) { - versionString = QString::fromCFString(reinterpret_cast(cfProductVersion)); + if (cfProductVersion && CFGetTypeID(cfProductVersion.get()) == CFStringGetTypeID()) { + versionString = toQStringRelease(reinterpret_cast(cfProductVersion.get())); } - CFRelease(cfProductVersion); - CFPropertyListRef cfBuildVersion = mLib.deviceCopyValue(device, 0, CFSTR("BuildVersion")); + const CFPropertyList_t cfBuildVersion( + mLib.deviceCopyValue(device, 0, CFSTR("BuildVersion"))); QString buildString; - if (cfBuildVersion && CFGetTypeID(cfBuildVersion) == CFStringGetTypeID()) { - buildString = QString::fromCFString(reinterpret_cast(cfBuildVersion)); + if (cfBuildVersion && CFGetTypeID(cfBuildVersion.get()) == CFStringGetTypeID()) { + buildString = QString::fromCFString(reinterpret_cast(cfBuildVersion.get())); } - CFRelease(cfBuildVersion); disconnectDevice(); if (findDeveloperDiskImage(versionString, buildString, path)) { - if (debugAll) - qDebug() << "Developers disk image found at" << path; + qCDebug(loggingCategory) << "Developers disk image found at" << path; if (signaturePath) { *signaturePath = QString("%1.%2").arg(*path).arg("signature"); return QFile::exists(*signaturePath); @@ -1359,14 +1443,14 @@ bool AppOpSession::installAppNew() CFSTR("1"), CFSTR("Developer"), CFSTR("1"), - (CFStringRef)dpath.get()}; + (CFStringRef) dpath.get()}; const CFDictionary_t options(CFDictionaryCreate(0, - reinterpret_cast(&keys[0]), - reinterpret_cast(&values[0]), - 7, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks)); + reinterpret_cast(&keys[0]), + reinterpret_cast(&values[0]), + 7, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); if (int error = mLib.deviceSecureInstallApplicationBundle(0, device, @@ -1404,30 +1488,33 @@ int AppOpSession::qmljsDebugPort() const if (match.hasMatch()) { bool ok; int res = match.captured(1).toInt(&ok); - if (ok && res >0 && res <= 0xFFFF) + if (ok && res > 0 && res <= 0xFFFF) return res; } } return 0; } - bool AppOpSession::runApp() { bool failure = (device == 0); QString exe = appPathOnDevice(); if (!mountDeveloperDiskImage()) { - addError(QString::fromLatin1("Running app \"%1\" failed. Mount developer disk failed.").arg(bundlePath)); + addError(QString::fromLatin1("Running app \"%1\" failed. Mount developer disk failed.") + .arg(bundlePath)); failure = true; } - CFStringRef keys[] = { CFSTR("MinIPhoneVersion"), CFSTR("MinAppleTVVersion") }; - CFStringRef values[] = { CFSTR("14.0"), CFSTR("14.0")}; - CFDictionaryRef version = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, - 2, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + CFStringRef keys[] = {CFSTR("MinIPhoneVersion"), CFSTR("MinAppleTVVersion")}; + CFStringRef values[] = {CFSTR("14.0"), CFSTR("14.0")}; + const CFDictionary_t version(CFDictionaryCreate(NULL, + (const void **) &keys, + (const void **) &values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); MobileDeviceLib &mLib = MobileDeviceLib::instance(); - bool useSecureProxy = mLib.deviceIsAtLeastVersionOnPlatform(device, version); + bool useSecureProxy = mLib.deviceIsAtLeastVersionOnPlatform(device, version.get()); // The debugserver service cannot be launched directly on iOS 14+ // A secure proxy service sits between the actual debugserver service. const QString &serviceName = useSecureProxy ? DebugSecureServiceName : DebugServiceName; @@ -1447,15 +1534,17 @@ bool AppOpSession::runApp() //if (!failure) failure = !expectGdbOkReply(gdbFd); // send the environment with a series of these commands... - if (!failure) failure = !sendGdbCommand(conn, "QEnvironmentHexEncoded:"); + if (!failure) + failure = !sendGdbCommand(conn, "QEnvironmentHexEncoded:"); // avoid address randomization to debug - if (!failure) failure = !sendGdbCommand(conn, "QSetDisableASLR:1"); - if (!failure) failure = !expectGdbOkReply(conn); + if (!failure) + failure = !sendGdbCommand(conn, "QSetDisableASLR:1"); + if (!failure) + failure = !expectGdbOkReply(conn); QStringList args = extraArgs; QByteArray runCommand("A"); args.insert(0, exe); - if (debugAll) - qDebug() << " trying to start " << args; + qCDebug(loggingCategory) << "trying to start" << args; for (int iarg = 0; iarg < args.size(); ++iarg) { if (iarg) runCommand.append(','); @@ -1466,10 +1555,14 @@ bool AppOpSession::runApp() runCommand.append(','); runCommand.append(arg); } - if (!failure) failure = !sendGdbCommand(conn, runCommand.constData(), runCommand.size()); - if (!failure) failure = !expectGdbOkReply(conn); - if (!failure) failure = !sendGdbCommand(conn, "qLaunchSuccess"); - if (!failure) failure = !expectGdbOkReply(conn); + if (!failure) + failure = !sendGdbCommand(conn, runCommand.constData(), runCommand.size()); + if (!failure) + failure = !expectGdbOkReply(conn); + if (!failure) + failure = !sendGdbCommand(conn, "qLaunchSuccess"); + if (!failure) + failure = !expectGdbOkReply(conn); } else { failure = true; } @@ -1482,16 +1575,14 @@ bool AppOpSession::runApp() void AppOpSession::reportProgress2(int progress, const QString &status) { - IosDeviceManagerPrivate::instance()->isTransferringApp( - bundlePath, deviceId, progress, status); + IosDeviceManagerPrivate::instance()->isTransferringApp(bundlePath, deviceId, progress, status); } QString AppOpSession::appId() { QSettings settings(bundlePath + QLatin1String("/Info.plist"), QSettings::NativeFormat); QString res = settings.value(QString::fromLatin1("CFBundleIdentifier")).toString(); - if (debugAll) - qDebug() << "appId:" << res; + qCDebug(loggingCategory) << "appId:" << res; return res; } @@ -1500,37 +1591,51 @@ QString AppOpSession::appPathOnDevice() QString res; if (!connectDevice()) return QString(); + CFDictionaryRef apps; - CFDictionaryRef options; - const void *attributes[3] = { (const void*)(CFSTR("CFBundleIdentifier")), - (const void*)(CFSTR("Path")), (const void*)(CFSTR("CFBundleExecutable")) }; - CFArrayRef lookupKeys = CFArrayCreate(kCFAllocatorDefault, (const void**)(&attributes[0]), 3, - &kCFTypeArrayCallBacks); + const void *attributes[3] = {(const void *) (CFSTR("CFBundleIdentifier")), + (const void *) (CFSTR("Path")), + (const void *) (CFSTR("CFBundleExecutable"))}; + CFArrayRef lookupKeys = CFArrayCreate(kCFAllocatorDefault, + (const void **) (&attributes[0]), + 3, + &kCFTypeArrayCallBacks); CFStringRef attrKey = CFSTR("ReturnAttributes"); - options = CFDictionaryCreate(kCFAllocatorDefault, (const void**)(&attrKey), - (const void**)(&lookupKeys), 1, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + const CFDictionary_t options(CFDictionaryCreate(kCFAllocatorDefault, + (const void **) (&attrKey), + (const void **) (&lookupKeys), + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); CFRelease(lookupKeys); + MobileDeviceLib &mLib = MobileDeviceLib::instance(); - if (int err = mLib.deviceLookupApplications(device, options, &apps)) { + if (int err = mLib.deviceLookupApplications(device, options.get(), &apps)) { addError(QString::fromLatin1("app lookup failed, AMDeviceLookupApplications returned %1") - .arg(err)); + .arg(err)); } - CFRelease(options); - if (debugAll) + + if (loggingCategory().isDebugEnabled()) CFShow(apps); + if (apps && CFGetTypeID(apps) == CFDictionaryGetTypeID()) { - CFStringRef cfAppId = appId().toCFString(); + CFString_t cfAppId(appId().toCFString()); CFDictionaryRef cfAppInfo = 0; - if (CFDictionaryGetValueIfPresent(apps, cfAppId, reinterpret_cast(&cfAppInfo))) { + if (CFDictionaryGetValueIfPresent(apps, + cfAppId.get(), + reinterpret_cast(&cfAppInfo))) { if (cfAppInfo && CFGetTypeID(cfAppInfo) == CFDictionaryGetTypeID()) { CFStringRef cfPath, cfBundleExe; QString path, bundleExe; - if (CFDictionaryGetValueIfPresent(cfAppInfo, CFSTR("Path"), reinterpret_cast(&cfPath))) + if (CFDictionaryGetValueIfPresent(cfAppInfo, + CFSTR("Path"), + reinterpret_cast(&cfPath))) path = QString::fromCFString(cfPath); - if (CFDictionaryGetValueIfPresent(cfAppInfo, CFSTR("CFBundleExecutable"), reinterpret_cast(&cfBundleExe))) + if (CFDictionaryGetValueIfPresent(cfAppInfo, + CFSTR("CFBundleExecutable"), + reinterpret_cast(&cfBundleExe))) bundleExe = QString::fromCFString(cfBundleExe); - if (!path.isEmpty() && ! bundleExe.isEmpty()) + if (!path.isEmpty() && !bundleExe.isEmpty()) res = path + QLatin1Char('/') + bundleExe; } } @@ -1539,29 +1644,15 @@ QString AppOpSession::appPathOnDevice() CFRelease(apps); disconnectDevice(); if (res.isEmpty()) - addError(QString::fromLatin1("failed to get app Path on device for bundle %1 with appId: %2") - .arg(bundlePath, appId())); + addError( + QString::fromLatin1("failed to get app Path on device for bundle %1 with appId: %2") + .arg(bundlePath, appId())); return res; } -am_res_t AppOpSession::appTransferCallback(CFDictionaryRef dict) -{ - if (debugAll) - qDebug() << "TransferAppSession::appTransferCallback"; - reportProgress(dict); - return 0; -} - -am_res_t AppOpSession::appInstallCallback(CFDictionaryRef dict) -{ - if (debugAll) - qDebug() << "TransferAppSession::appInstallCallback"; - reportProgress(dict); - return 0; -} - -DevInfoSession::DevInfoSession(const QString &deviceId) : CommandSession(deviceId) -{ } +DevInfoSession::DevInfoSession(const QString &deviceId) + : CommandSession(deviceId) +{} QString DevInfoSession::commandName() { @@ -1575,20 +1666,18 @@ QString DevInfoSession::getStringValue(AMDevice *device, { QString value = fallback; MobileDeviceLib &mLib = MobileDeviceLib::instance(); - CFPropertyListRef cfValue = mLib.deviceCopyValue(device, domain, key); + CFPropertyList_t cfValue(mLib.deviceCopyValue(device, domain, key)); if (cfValue) { - if (CFGetTypeID(cfValue) == CFStringGetTypeID()) - value = QString::fromCFString(reinterpret_cast(cfValue)); - CFRelease(cfValue); + if (CFGetTypeID(cfValue.get()) == CFStringGetTypeID()) + value = QString::fromCFString(reinterpret_cast(cfValue.get())); } return value; } void DevInfoSession::deviceCallbackReturned() { - if (debugAll) - qDebug() << "device available"; - QMap res; + qCDebug(loggingCategory) << "device available"; + QMap res; const QString deviceNameKey = "deviceName"; const QString developerStatusKey = "developerStatus"; const QString deviceConnectedKey = "deviceConnected"; @@ -1624,8 +1713,7 @@ void DevInfoSession::deviceCallbackReturned() res[deviceNameKey] = QLatin1String("*unknown*"); if (!res.contains(developerStatusKey)) res[developerStatusKey] = QLatin1String("*unknown*"); - if (debugAll) - qDebug() << "deviceInfo:" << res << ", failure:" << failure; + qCDebug(loggingCategory) << "deviceInfo:" << res << ", failure:" << failure; emit Ios::IosDeviceManager::instance()->deviceInfo(deviceId, res); /* should we also check the provision profiles??? i.e. int fd; @@ -1635,13 +1723,11 @@ void DevInfoSession::deviceCallbackReturned() // ------- MobileDeviceLib implementation -------- - - void CommandSession::internalDeviceAvailableCallback(QString deviceId, AMDeviceRef device) { if (deviceId != this->deviceId && !this->deviceId.isEmpty()) addError(QString::fromLatin1("deviceId mismatch in deviceAvailableCallback, %1 vs %2") - .arg(deviceId, this->deviceId)); + .arg(deviceId, this->deviceId)); this->deviceId = deviceId; if (this->device) addError(QString::fromLatin1("session had non null device in deviceAvailableCallback")); @@ -1659,13 +1745,14 @@ IosDeviceManager *IosDeviceManager::instance() return &instanceVal; } -IosDeviceManager::IosDeviceManager(QObject *parent) : - QObject(parent) +IosDeviceManager::IosDeviceManager(QObject *parent) + : QObject(parent) { d = new Internal::IosDeviceManagerPrivate(this); } -bool IosDeviceManager::watchDevices() { +bool IosDeviceManager::watchDevices() +{ return d->watchDevices(); } @@ -1694,7 +1781,8 @@ void IosDeviceManager::stopGdbServer(ServiceConnRef conn, int phase) return d->stopGdbServer(conn, phase); } -QStringList IosDeviceManager::errors() { +QStringList IosDeviceManager::errors() +{ return d->errors(); } diff --git a/src/tools/iostool/iostool.cpp b/src/tools/iostool/iostool.cpp index 2def3afa74a..56648a2fd5b 100644 --- a/src/tools/iostool/iostool.cpp +++ b/src/tools/iostool/iostool.cpp @@ -28,6 +28,7 @@ #include "relayserver.h" #include "gdbrunner.h" +#include #include #include #include @@ -37,19 +38,10 @@ namespace Ios { IosTool::IosTool(QObject *parent): QObject(parent), - maxProgress(0), - opLeft(0), - debug(false), - inAppOutput(false), - splitAppOutput(true), - appOp(IosDeviceManager::None), - outFile(), - out(&outFile), - gdbServer(0), - qmlServer(0) + m_xmlWriter(&m_outputFile) { - outFile.open(stdout, QIODevice::WriteOnly, QFileDevice::DontCloseHandle); - out.setAutoFormatting(true); + m_outputFile.open(stdout, QIODevice::WriteOnly, QFileDevice::DontCloseHandle); + m_xmlWriter.setAutoFormatting(true); } IosTool::~IosTool() @@ -66,73 +58,83 @@ void IosTool::run(const QStringList &args) int timeout = 1000; QStringList extraArgs; - out.writeStartDocument(); - out.writeStartElement(QLatin1String("query_result")); - for (int iarg = 1; iarg < args.size(); ++iarg) { - const QString &arg = args[iarg]; - if (arg == QLatin1String("-i") || arg == QLatin1String("--id")) { - if (++iarg == args.size()) { - writeMsg(QStringLiteral("missing device id value after ") + arg); - printHelp = true; - } - deviceId = args.value(iarg); - } else if (arg == QLatin1String("-b") || arg == QLatin1String("--bundle")) { - if (++iarg == args.size()) { - writeMsg(QStringLiteral("missing bundle path after ") + arg); - printHelp = true; - } - bundlePath = args.value(iarg); - } else if (arg == QLatin1String("--delta-path")) { - if (++iarg == args.size()) { - writeMsg(QStringLiteral("missing path after ") + arg); - printHelp = true; - } - m_deltasPath = args.value(iarg); - } else if (arg == QLatin1String("--install")) { - appOp = IosDeviceManager::AppOp(appOp | IosDeviceManager::Install); - } else if (arg == QLatin1String("--run")) { - appOp = IosDeviceManager::AppOp(appOp | IosDeviceManager::Run); - } else if (arg == QLatin1String("--noninteractive")) { - // ignored for compatibility - } else if (arg == QLatin1String("-v") || arg == QLatin1String("--verbose")) { - m_echoRelays = true; - } else if (arg == QLatin1String("-d") || arg == QLatin1String("--debug")) { - appOp = IosDeviceManager::AppOp(appOp | IosDeviceManager::Run); - debug = true; - } else if (arg == QLatin1String("--device-info")) { - deviceInfo = true; - } else if (arg == QLatin1String("-t") || arg == QLatin1String("--timeout")) { - if (++iarg == args.size()) { - writeMsg(QStringLiteral("missing timeout value after ") + arg); - printHelp = true; - } - bool ok = false; - int tOut = args.value(iarg).toInt(&ok); - if (ok && tOut > 0) { - timeout = tOut; - } else { - writeMsg("timeout value should be an integer"); - printHelp = true; - } - } else if (arg == QLatin1String("-a") || arg == QLatin1String("--args")) { - extraArgs = args.mid(iarg + 1, args.size() - iarg - 1); - iarg = args.size(); - } else if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) { + m_xmlWriter.writeStartDocument(); + m_xmlWriter.writeStartElement(QLatin1String("query_result")); + + QCommandLineParser cmdLineParser; + cmdLineParser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); + cmdLineParser.setApplicationDescription("iOS Deployment and run helper"); + + const QList options{ + QCommandLineOption(QStringList{"h", "help"}), + QCommandLineOption(QStringList{"i", "id"}, "target device id", "id"), + QCommandLineOption(QStringList{"b", "bundle"}, "path to the target bundle.app", "bundle"), + QCommandLineOption("delta-path", "path to the deploy delta directory", "delta-path"), + QCommandLineOption("install", "Install a bundle on a device"), + QCommandLineOption(QStringList{"r", "run"}, "Run the bundle on the device"), + QCommandLineOption(QStringList{"d", "debug"}, "Debug the bundle on the device"), + QCommandLineOption("device-info", "Retrieve information about the selected device"), + QCommandLineOption(QStringList{"t", "timeout"}, "Operation timeout (s)", "timeout"), + QCommandLineOption(QStringList{"v", "verbose"}, "Verbose output"), + }; + + cmdLineParser.addOptions(options); + + cmdLineParser.process(args); + + if (cmdLineParser.isSet("verbose")) + m_echoRelays = true; + + if (cmdLineParser.isSet("id")) + deviceId = cmdLineParser.value("id"); + + if (cmdLineParser.isSet("bundle")) + bundlePath = cmdLineParser.value("bundle"); + + if (cmdLineParser.isSet("delta-path")) + m_deltasPath = cmdLineParser.value("delta-path"); + + if (cmdLineParser.isSet("install")) { + m_requestedOperation = IosDeviceManager::AppOp(m_requestedOperation + | IosDeviceManager::Install); + } + else if (cmdLineParser.isSet("run")) { + m_requestedOperation = IosDeviceManager::AppOp(m_requestedOperation | IosDeviceManager::Run); + } + + if (cmdLineParser.isSet("debug")) { + m_requestedOperation = IosDeviceManager::AppOp(m_requestedOperation | IosDeviceManager::Run); + m_debug = true; + } + + if (cmdLineParser.isSet("device-info")) + deviceInfo = true; + + if (cmdLineParser.isSet("timeout")) { + bool ok = false; + timeout = cmdLineParser.value("timeout").toInt(&ok); + if (!ok || timeout < 0) { + writeMsg("timeout value should be an integer"); printHelp = true; - } else { - writeMsg(QString::fromLatin1("unexpected argument \"%1\"").arg(arg)); } } - if (printHelp) { - out.writeStartElement(QLatin1String("msg")); - out.writeCharacters(QLatin1String("iostool [--id ] [--bundle ] [--install] [--run] [--debug]\n")); - out.writeCharacters(QLatin1String(" [--device-info] [--timeout ] [--verbose]\n")); // to do pass in env as stub does - out.writeCharacters(QLatin1String(" [--args ]")); - out.writeEndElement(); + + extraArgs = cmdLineParser.positionalArguments(); + + if (printHelp || cmdLineParser.isSet("help")) { + m_xmlWriter.writeStartElement(QLatin1String("msg")); + m_xmlWriter.writeCharacters( + QLatin1String("iostool [--id ] [--bundle ] [--delta-path] " + "[--install] [--run] [--debug]\n")); + m_xmlWriter.writeCharacters(QLatin1String( + " [--device-info] [--timeout ] [--verbose]\n")); // to do pass in env as stub does + m_xmlWriter.writeCharacters(QLatin1String(" [-- ]")); + m_xmlWriter.writeEndElement(); doExit(-1); return; } - outFile.flush(); + + m_outputFile.flush(); connect(manager, &IosDeviceManager::isTransferringApp, this, &IosTool::isTransferringApp); connect(manager, &IosDeviceManager::didTransferApp, this, &IosTool::didTransferApp); connect(manager, &IosDeviceManager::didStartApp, this, &IosTool::didStartApp); @@ -154,35 +156,35 @@ void IosTool::run(const QStringList &args) if (deviceInfo) { if (!bundlePath.isEmpty()) writeMsg("--device-info overrides --bundle"); - ++opLeft; + ++m_operationsRemaining; manager->requestDeviceInfo(deviceId, timeout); } else if (!bundlePath.isEmpty()) { - switch (appOp) { + switch (m_requestedOperation) { case IosDeviceManager::None: break; case IosDeviceManager::Install: case IosDeviceManager::Run: - ++opLeft; + ++m_operationsRemaining; break; case IosDeviceManager::InstallAndRun: - opLeft += 2; + m_operationsRemaining += 2; break; } - maxProgress = 200; - manager->requestAppOp(bundlePath, extraArgs, appOp, deviceId, timeout, m_deltasPath); + m_maxProgress = 200; + manager->requestAppOp(bundlePath, extraArgs, m_requestedOperation, deviceId, timeout, m_deltasPath); } - if (opLeft == 0) + if (m_operationsRemaining == 0) doExit(0); } void IosTool::stopXml(int errorCode) { QMutexLocker l(&m_xmlMutex); - out.writeEmptyElement(QLatin1String("exit")); - out.writeAttribute(QLatin1String("code"), QString::number(errorCode)); - out.writeEndElement(); // result element (hopefully) - out.writeEndDocument(); - outFile.flush(); + m_xmlWriter.writeEmptyElement(QLatin1String("exit")); + m_xmlWriter.writeAttribute(QLatin1String("code"), QString::number(errorCode)); + m_xmlWriter.writeEndElement(); // result element (hopefully) + m_xmlWriter.writeEndDocument(); + m_outputFile.flush(); } void IosTool::doExit(int errorCode) @@ -198,12 +200,12 @@ void IosTool::isTransferringApp(const QString &bundlePath, const QString &device Q_UNUSED(bundlePath) Q_UNUSED(deviceId) QMutexLocker l(&m_xmlMutex); - out.writeStartElement(QLatin1String("status")); - out.writeAttribute(QLatin1String("progress"), QString::number(progress)); - out.writeAttribute(QLatin1String("max_progress"), QString::number(maxProgress)); - out.writeCharacters(info); - out.writeEndElement(); - outFile.flush(); + m_xmlWriter.writeStartElement(QLatin1String("status")); + m_xmlWriter.writeAttribute(QLatin1String("progress"), QString::number(progress)); + m_xmlWriter.writeAttribute(QLatin1String("max_progress"), QString::number(m_maxProgress)); + m_xmlWriter.writeCharacters(info); + m_xmlWriter.writeEndElement(); + m_outputFile.flush(); } void IosTool::didTransferApp(const QString &bundlePath, const QString &deviceId, @@ -214,21 +216,21 @@ void IosTool::didTransferApp(const QString &bundlePath, const QString &deviceId, { QMutexLocker l(&m_xmlMutex); if (status == IosDeviceManager::Success) { - out.writeStartElement(QLatin1String("status")); - out.writeAttribute(QLatin1String("progress"), QString::number(maxProgress)); - out.writeAttribute(QLatin1String("max_progress"), QString::number(maxProgress)); - out.writeCharacters(QLatin1String("App Transferred")); - out.writeEndElement(); + m_xmlWriter.writeStartElement(QLatin1String("status")); + m_xmlWriter.writeAttribute(QLatin1String("progress"), QString::number(m_maxProgress)); + m_xmlWriter.writeAttribute(QLatin1String("max_progress"), QString::number(m_maxProgress)); + m_xmlWriter.writeCharacters(QLatin1String("App Transferred")); + m_xmlWriter.writeEndElement(); } - out.writeEmptyElement(QLatin1String("app_transfer")); - out.writeAttribute(QLatin1String("status"), + m_xmlWriter.writeEmptyElement(QLatin1String("app_transfer")); + m_xmlWriter.writeAttribute(QLatin1String("status"), (status == IosDeviceManager::Success) ? QLatin1String("SUCCESS") : QLatin1String("FAILURE")); //out.writeCharacters(QString()); // trigger a complete closing of the empty element - outFile.flush(); + m_outputFile.flush(); } - if (status != IosDeviceManager::Success || --opLeft == 0) + if (status != IosDeviceManager::Success || --m_operationsRemaining == 0) doExit((status == IosDeviceManager::Success) ? 0 : -1); } @@ -240,15 +242,15 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId, Q_UNUSED(deviceId) { QMutexLocker l(&m_xmlMutex); - out.writeEmptyElement(QLatin1String("app_started")); - out.writeAttribute(QLatin1String("status"), + m_xmlWriter.writeEmptyElement(QLatin1String("app_started")); + m_xmlWriter.writeAttribute(QLatin1String("status"), (status == IosDeviceManager::Success) ? QLatin1String("SUCCESS") : QLatin1String("FAILURE")); //out.writeCharacters(QString()); // trigger a complete closing of the empty element - outFile.flush(); + m_outputFile.flush(); } - if (status != IosDeviceManager::Success || appOp == IosDeviceManager::Install) { + if (status != IosDeviceManager::Success || m_requestedOperation == IosDeviceManager::Install) { doExit(); return; } @@ -257,43 +259,44 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId, doExit(-2); return; } - if (appOp != IosDeviceManager::InstallAndRun && appOp != IosDeviceManager::Run) { - writeMsg(QString::fromLatin1("unexpected appOp value %1").arg(appOp)); + if (m_requestedOperation != IosDeviceManager::InstallAndRun && m_requestedOperation != IosDeviceManager::Run) { + writeMsg(QString::fromLatin1("unexpected appOp value %1").arg(m_requestedOperation)); doExit(-3); return; } if (deviceSession) { int qmlPort = deviceSession->qmljsDebugPort(); if (qmlPort) { - qmlServer = new QmlRelayServer(this, qmlPort, deviceSession); - qmlServer->startServer(); + m_qmlServer = std::make_unique(this, qmlPort, deviceSession); + m_qmlServer->startServer(); } } - if (debug) { - gdbServer = new GdbRelayServer(this, gdbFd, conn); - if (!gdbServer->startServer()) { + if (m_debug) { + m_gdbServer = std::make_unique(this, gdbFd, conn); + if (!m_gdbServer->startServer()) { doExit(-4); return; } } { QMutexLocker l(&m_xmlMutex); - out.writeStartElement(QLatin1String("server_ports")); - out.writeAttribute(QLatin1String("gdb_server"), - QString::number(gdbServer ? gdbServer->serverPort() : -1)); - out.writeAttribute(QLatin1String("qml_server"), - QString::number(qmlServer ? qmlServer->serverPort() : -1)); - out.writeEndElement(); - outFile.flush(); + m_xmlWriter.writeStartElement(QLatin1String("server_ports")); + m_xmlWriter.writeAttribute(QLatin1String("gdb_server"), + QString::number(m_gdbServer ? m_gdbServer->serverPort() : -1)); + m_xmlWriter.writeAttribute(QLatin1String("qml_server"), + QString::number(m_qmlServer ? m_qmlServer->serverPort() : -1)); + m_xmlWriter.writeEndElement(); + m_outputFile.flush(); } - if (!debug) { - gdbRunner = new GdbRunner(this, conn); + if (!m_debug) { + m_gdbRunner = std::make_unique(this, conn); + // we should not stop the event handling of the main thread // all output moves to the new thread (other option would be to signal it back) QThread *gdbProcessThread = new QThread(); - gdbRunner->moveToThread(gdbProcessThread); - QObject::connect(gdbProcessThread, &QThread::started, gdbRunner, &GdbRunner::run); - QObject::connect(gdbRunner, &GdbRunner::finished, gdbProcessThread, &QThread::quit); + m_gdbRunner->moveToThread(gdbProcessThread); + QObject::connect(gdbProcessThread, &QThread::started, m_gdbRunner.get(), &GdbRunner::run); + QObject::connect(m_gdbRunner.get(), &GdbRunner::finished, gdbProcessThread, &QThread::quit); QObject::connect(gdbProcessThread, &QThread::finished, gdbProcessThread, &QObject::deleteLater); gdbProcessThread->start(); @@ -310,11 +313,11 @@ void IosTool::writeMsg(const char *msg) void IosTool::writeMsg(const QString &msg) { QMutexLocker l(&m_xmlMutex); - out.writeStartElement(QLatin1String("msg")); + m_xmlWriter.writeStartElement(QLatin1String("msg")); writeTextInElement(msg); - out.writeCharacters(QLatin1String("\n")); - out.writeEndElement(); - outFile.flush(); + m_xmlWriter.writeCharacters(QLatin1String("\n")); + m_xmlWriter.writeEndElement(); + m_outputFile.flush(); } void IosTool::writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len) @@ -331,9 +334,9 @@ void IosTool::writeMaybeBin(const QString &extraMsg, const char *msg, quintptr l buf2[2 * len + 3] = 0; QMutexLocker l(&m_xmlMutex); - out.writeStartElement(QLatin1String("msg")); - out.writeCharacters(extraMsg); - out.writeCharacters(QLatin1String(buf2)); + m_xmlWriter.writeStartElement(QLatin1String("msg")); + m_xmlWriter.writeCharacters(extraMsg); + m_xmlWriter.writeCharacters(QLatin1String(buf2)); for (quintptr i = 0; i < len; ++i) { if (msg[i] < 0x20 || msg[i] > 0x7f) buf2[i] = '_'; @@ -341,10 +344,10 @@ void IosTool::writeMaybeBin(const QString &extraMsg, const char *msg, quintptr l buf2[i] = msg[i]; } buf2[len] = 0; - out.writeCharacters(QLatin1String(buf2)); + m_xmlWriter.writeCharacters(QLatin1String(buf2)); delete[] buf2; - out.writeEndElement(); - outFile.flush(); + m_xmlWriter.writeEndElement(); + m_outputFile.flush(); } void IosTool::deviceInfo(const QString &deviceId, const IosDeviceManager::Dict &devInfo) @@ -352,16 +355,16 @@ void IosTool::deviceInfo(const QString &deviceId, const IosDeviceManager::Dict & Q_UNUSED(deviceId) { QMutexLocker l(&m_xmlMutex); - out.writeTextElement(QLatin1String("device_id"), deviceId); - out.writeStartElement(QLatin1String("device_info")); + m_xmlWriter.writeTextElement(QLatin1String("device_id"), deviceId); + m_xmlWriter.writeStartElement(QLatin1String("device_info")); for (auto i = devInfo.cbegin(); i != devInfo.cend(); ++i) { - out.writeStartElement(QLatin1String("item")); - out.writeTextElement(QLatin1String("key"), i.key()); - out.writeTextElement(QLatin1String("value"), i.value()); - out.writeEndElement(); + m_xmlWriter.writeStartElement(QLatin1String("item")); + m_xmlWriter.writeTextElement(QLatin1String("key"), i.key()); + m_xmlWriter.writeTextElement(QLatin1String("value"), i.value()); + m_xmlWriter.writeEndElement(); } - out.writeEndElement(); - outFile.flush(); + m_xmlWriter.writeEndElement(); + m_outputFile.flush(); } doExit(); } @@ -374,24 +377,24 @@ void IosTool::writeTextInElement(const QString &output) while ((pos = output.indexOf(controlCharRe, pos)) != -1) { QMutexLocker l(&m_xmlMutex); - out.writeCharacters(output.mid(oldPos, pos - oldPos)); - out.writeEmptyElement(QLatin1String("control_char")); - out.writeAttribute(QLatin1String("code"), QString::number(output.at(pos).toLatin1())); + m_xmlWriter.writeCharacters(output.mid(oldPos, pos - oldPos)); + m_xmlWriter.writeEmptyElement(QLatin1String("control_char")); + m_xmlWriter.writeAttribute(QLatin1String("code"), QString::number(output.at(pos).toLatin1())); pos += 1; oldPos = pos; } - out.writeCharacters(output.mid(oldPos, output.length() - oldPos)); + m_xmlWriter.writeCharacters(output.mid(oldPos, output.length() - oldPos)); } void IosTool::appOutput(const QString &output) { QMutexLocker l(&m_xmlMutex); - if (!inAppOutput) - out.writeStartElement(QLatin1String("app_output")); + if (!m_inAppOutput) + m_xmlWriter.writeStartElement(QLatin1String("app_output")); writeTextInElement(output); - if (!inAppOutput) - out.writeEndElement(); - outFile.flush(); + if (!m_inAppOutput) + m_xmlWriter.writeEndElement(); + m_outputFile.flush(); } void IosTool::readStdin() @@ -412,26 +415,26 @@ void IosTool::errorMsg(const QString &msg) void IosTool::stopGdbRunner() { - if (gdbRunner) { - gdbRunner->stop(0); + if (m_gdbRunner) { + m_gdbRunner->stop(0); QTimer::singleShot(100, this, &IosTool::stopGdbRunner2); } } void IosTool::stopGdbRunner2() { - if (gdbRunner) - gdbRunner->stop(1); + if (m_gdbRunner) + m_gdbRunner->stop(1); } void IosTool::stopRelayServers(int errorCode) { if (echoRelays()) writeMsg("gdbServerStops"); - if (qmlServer) - qmlServer->stopServer(); - if (gdbServer) - gdbServer->stopServer(); + if (m_qmlServer) + m_qmlServer->stopServer(); + if (m_gdbServer) + m_gdbServer->stopServer(); doExit(errorCode); } diff --git a/src/tools/iostool/iostool.h b/src/tools/iostool/iostool.h index c71a30e6d8c..92b2ad20a12 100644 --- a/src/tools/iostool/iostool.h +++ b/src/tools/iostool/iostool.h @@ -40,6 +40,8 @@ class QmlRelayServer; class IosTool: public QObject { + friend class GdbRunner; + Q_OBJECT public: @@ -71,20 +73,19 @@ private: void readStdin(); QRecursiveMutex m_xmlMutex; - int maxProgress; - int opLeft; - bool debug; - bool inAppOutput; - bool splitAppOutput; // as QXmlStreamReader reports the text attributes atomically it is better to split - Ios::IosDeviceManager::AppOp appOp; - QFile outFile; + int m_maxProgress = 0; + int m_operationsRemaining = 0; + bool m_debug = false; + bool m_inAppOutput = false; + bool m_splitAppOutput = true; // as QXmlStreamReader reports the text attributes atomically it is better to split + IosDeviceManager::AppOp m_requestedOperation{IosDeviceManager::AppOp::None}; + QFile m_outputFile; QString m_qmlPort; QString m_deltasPath; - QXmlStreamWriter out; - GdbRelayServer *gdbServer; - QmlRelayServer *qmlServer; - GdbRunner *gdbRunner; + QXmlStreamWriter m_xmlWriter; + std::unique_ptr m_gdbServer; + std::unique_ptr m_qmlServer; + std::unique_ptr m_gdbRunner; bool m_echoRelays = false; - friend class GdbRunner; }; } diff --git a/src/tools/iostool/main.cpp b/src/tools/iostool/main.cpp index a453010eb92..5e9c7a78276 100644 --- a/src/tools/iostool/main.cpp +++ b/src/tools/iostool/main.cpp @@ -25,13 +25,15 @@ #include "iostool.h" -#include +#include #include int main(int argc, char *argv[]) { - //This keeps iostool from stealing focus - qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "true"); + // Make sure that our runloop uses the CFRunLoop dispatcher. + // Otherwise the MobileDevice.Framework notifications won't work. + qputenv("QT_EVENT_DISPATCHER_CORE_FOUNDATION", "1"); + // We do not pass the real arguments to QCoreApplication because this wrapper needs to be able // to forward arguments like -qmljsdebugger=... that are filtered by QCoreApplication QStringList args; @@ -44,7 +46,10 @@ int main(int argc, char *argv[]) qtArgc = 1; } - QGuiApplication a(qtArgc, &qtArg); + QCoreApplication a(qtArgc, &qtArg); + QCoreApplication::setApplicationName("iostool"); + QCoreApplication::setApplicationVersion("1.0"); + Ios::IosTool tool; tool.run(args); int res = a.exec(); diff --git a/src/tools/iostool/mobiledevicelib.cpp b/src/tools/iostool/mobiledevicelib.cpp index ae1c70f4a86..40d2f1c4616 100644 --- a/src/tools/iostool/mobiledevicelib.cpp +++ b/src/tools/iostool/mobiledevicelib.cpp @@ -24,9 +24,15 @@ ****************************************************************************/ #include "mobiledevicelib.h" +#include "cfutils.h" #include +#include +#include +namespace { +Q_LOGGING_CATEGORY(loggingCategory, "qtc.iostool.mobiledevicelib") +} #ifdef MOBILE_DEV_DIRECT_LINK #include "MobileDevice.h" @@ -51,6 +57,14 @@ MobileDeviceLib::MobileDeviceLib() setLogLevel(5); } +template +void MobileDeviceLib::resolveFunction(const char *functionName, T &functionPtr) { + functionPtr = reinterpret_cast(m_mobileDeviceLib.resolve(functionName)); + if (!functionPtr) { + addError(QLatin1String("MobileDeviceLib does not define ") + functionName); + } +} + bool MobileDeviceLib::load() { #ifdef MOBILE_DEV_DIRECT_LINK @@ -75,116 +89,46 @@ bool MobileDeviceLib::load() //m_AMDeviceLookupApplications = &AMDeviceLookupApplications; m_USBMuxConnectByPort = &USBMuxConnectByPort; #else - QLibrary *libAppleFSCompression = new QLibrary(QLatin1String("/System/Library/PrivateFrameworks/AppleFSCompression.framework/AppleFSCompression")); - if (!libAppleFSCompression->load()) - addError("MobileDevice dependency AppleFSCompression failed to load"); - deps << libAppleFSCompression; - QLibrary *libBom = new QLibrary(QLatin1String("/System/Library/PrivateFrameworks/Bom.framework/Bom")); - if (!libBom->load()) - addError("MobileDevice dependency Bom failed to load"); - deps << libBom; - lib.setFileName(QLatin1String("/System/Library/PrivateFrameworks/MobileDevice.framework/MobileDevice")); - if (!lib.load()) + m_mobileDeviceLib.setFileName("/System/Library/PrivateFrameworks/MobileDevice.framework/MobileDevice"); + if (!m_mobileDeviceLib.load()) return false; - m_AMDSetLogLevel = reinterpret_cast(lib.resolve("AMDSetLogLevel")); - if (m_AMDSetLogLevel == 0) - addError("MobileDeviceLib does not define AMDSetLogLevel"); - m_AMDeviceSecureInstallApplicationBundle - = reinterpret_cast( - lib.resolve("AMDeviceSecureInstallApplicationBundle")); - if (m_AMDeviceSecureInstallApplicationBundle == 0) - addError("MobileDeviceLib does not define m_AMDeviceSecureInstallApplicationBundle"); - - m_AMDeviceNotificationSubscribe = reinterpret_cast( - lib.resolve("AMDeviceNotificationSubscribe")); - if (m_AMDeviceNotificationSubscribe == 0) - addError("MobileDeviceLib does not define AMDeviceNotificationSubscribe"); - m_AMDeviceNotificationUnsubscribe = reinterpret_cast(lib.resolve("AMDeviceNotificationUnsubscribe")); - if (m_AMDeviceNotificationUnsubscribe == 0) - addError("MobileDeviceLib does not define AMDeviceNotificationUnsubscribe"); - m_AMDeviceGetInterfaceType = reinterpret_cast(lib.resolve("AMDeviceGetInterfaceType")); - if (m_AMDeviceGetInterfaceType == 0) - addError("MobileDeviceLib does not define AMDeviceGetInterfaceType"); - m_AMDeviceCopyValue = reinterpret_cast(lib.resolve("AMDeviceCopyValue")); - if (m_AMDSetLogLevel == 0) - addError("MobileDeviceLib does not define AMDSetLogLevel"); - m_AMDeviceGetConnectionID = reinterpret_cast(lib.resolve("AMDeviceGetConnectionID")); - if (m_AMDeviceGetConnectionID == 0) - addError("MobileDeviceLib does not define AMDeviceGetConnectionID"); - m_AMDeviceCopyDeviceIdentifier = reinterpret_cast(lib.resolve("AMDeviceCopyDeviceIdentifier")); - if (m_AMDeviceCopyDeviceIdentifier == 0) - addError("MobileDeviceLib does not define AMDeviceCopyDeviceIdentifier"); - m_AMDeviceConnect = reinterpret_cast(lib.resolve("AMDeviceConnect")); - if (m_AMDeviceConnect == 0) - addError("MobileDeviceLib does not define AMDeviceConnect"); - m_AMDevicePair = reinterpret_cast(lib.resolve("AMDevicePair")); - if (m_AMDevicePair == 0) - addError("MobileDeviceLib does not define AMDevicePair"); - m_AMDeviceIsPaired = reinterpret_cast(lib.resolve("AMDeviceIsPaired")); - if (m_AMDeviceIsPaired == 0) - addError("MobileDeviceLib does not define AMDeviceIsPaired"); - m_AMDeviceValidatePairing = reinterpret_cast(lib.resolve("AMDeviceValidatePairing")); - if (m_AMDeviceValidatePairing == 0) - addError("MobileDeviceLib does not define AMDeviceValidatePairing"); - m_AMDeviceStartSession = reinterpret_cast(lib.resolve("AMDeviceStartSession")); - if (m_AMDeviceStartSession == 0) - addError("MobileDeviceLib does not define AMDeviceStartSession"); - m_AMDeviceStopSession = reinterpret_cast(lib.resolve("AMDeviceStopSession")); - if (m_AMDeviceStopSession == 0) - addError("MobileDeviceLib does not define AMDeviceStopSession"); - m_AMDeviceDisconnect = reinterpret_cast(lib.resolve("AMDeviceDisconnect")); - if (m_AMDeviceDisconnect == 0) - addError("MobileDeviceLib does not define AMDeviceDisconnect"); - m_AMDeviceMountImage = reinterpret_cast(lib.resolve("AMDeviceMountImage")); - if (m_AMDeviceMountImage == 0) - addError("MobileDeviceLib does not define AMDeviceMountImage"); - m_AMDeviceSecureStartService = reinterpret_cast(lib.resolve("AMDeviceSecureStartService")); - if (m_AMDeviceSecureStartService == 0) - addError("MobileDeviceLib does not define AMDeviceSecureStartService"); - m_AMDeviceSecureTransferPath = reinterpret_cast(lib.resolve("AMDeviceSecureTransferPath")); - if (m_AMDeviceSecureTransferPath == 0) - addError("MobileDeviceLib does not define AMDeviceSecureTransferPath"); - m_AMDeviceSecureInstallApplication = reinterpret_cast(lib.resolve("AMDeviceSecureInstallApplication")); - if (m_AMDeviceSecureInstallApplication == 0) - addError("MobileDeviceLib does not define AMDeviceSecureInstallApplication"); - m_AMDServiceConnectionGetSocket = reinterpret_cast(lib.resolve("AMDServiceConnectionGetSocket")); - if (m_AMDServiceConnectionGetSocket == nullptr) - addError("MobileDeviceLib does not define AMDServiceConnectionGetSocket"); - m_AMDeviceUninstallApplication = reinterpret_cast(lib.resolve("AMDeviceUninstallApplication")); - m_AMDServiceConnectionSend = reinterpret_cast(lib.resolve("AMDServiceConnectionSend")); - if (m_AMDServiceConnectionSend == nullptr) - addError("MobileDeviceLib does not define AMDServiceConnectionSend"); - m_AMDServiceConnectionReceive = reinterpret_cast(lib.resolve("AMDServiceConnectionReceive")); - if (m_AMDServiceConnectionReceive == nullptr) - addError("MobileDeviceLib does not define AMDServiceConnectionReceive"); - m_AMDServiceConnectionInvalidate = reinterpret_cast(lib.resolve("AMDServiceConnectionInvalidate")); - if (m_AMDServiceConnectionInvalidate == nullptr) - addError("MobileDeviceLib does not define AMDServiceConnectionInvalidate"); - m_AMDeviceIsAtLeastVersionOnPlatform = reinterpret_cast(lib.resolve("AMDeviceIsAtLeastVersionOnPlatform")); - if (m_AMDeviceIsAtLeastVersionOnPlatform == nullptr) - addError("MobileDeviceLib does not define AMDeviceIsAtLeastVersionOnPlatform"); - if (m_AMDeviceUninstallApplication == 0) - addError("MobileDeviceLib does not define AMDeviceUninstallApplication"); - m_AMDeviceLookupApplications = reinterpret_cast(lib.resolve("AMDeviceLookupApplications")); - if (m_AMDeviceLookupApplications == 0) - addError("MobileDeviceLib does not define AMDeviceLookupApplications"); - m_AMDErrorString = reinterpret_cast(lib.resolve("AMDErrorString")); - if (m_AMDErrorString == 0) - addError("MobileDeviceLib does not define AMDErrorString"); - m_MISCopyErrorStringForErrorCode = reinterpret_cast(lib.resolve("MISCopyErrorStringForErrorCode")); - if (m_MISCopyErrorStringForErrorCode == 0) - addError("MobileDeviceLib does not define MISCopyErrorStringForErrorCode"); - m_USBMuxConnectByPort = reinterpret_cast(lib.resolve("USBMuxConnectByPort")); - if (m_USBMuxConnectByPort == 0) - addError("MobileDeviceLib does not define USBMuxConnectByPort"); + resolveFunction("AMDSetLogLevel", m_AMDSetLogLevel); + resolveFunction("AMDeviceSecureInstallApplicationBundle", m_AMDeviceSecureInstallApplicationBundle); + resolveFunction("AMDeviceNotificationSubscribe", m_AMDeviceNotificationSubscribe); + resolveFunction("AMDeviceNotificationUnsubscribe", m_AMDeviceNotificationUnsubscribe); + resolveFunction("AMDeviceGetInterfaceType", m_AMDeviceGetInterfaceType); + resolveFunction("AMDeviceCopyValue", m_AMDeviceCopyValue); + resolveFunction("AMDeviceGetConnectionID", m_AMDeviceGetConnectionID); + resolveFunction("AMDeviceCopyDeviceIdentifier", m_AMDeviceCopyDeviceIdentifier); + resolveFunction("AMDeviceConnect", m_AMDeviceConnect); + resolveFunction("AMDevicePair", m_AMDevicePair); + resolveFunction("AMDeviceIsPaired", m_AMDeviceIsPaired); + resolveFunction("AMDeviceValidatePairing", m_AMDeviceValidatePairing); + resolveFunction("AMDeviceStartSession", m_AMDeviceStartSession); + resolveFunction("AMDeviceStopSession", m_AMDeviceStopSession); + resolveFunction("AMDeviceDisconnect", m_AMDeviceDisconnect); + resolveFunction("AMDeviceMountImage", m_AMDeviceMountImage); + resolveFunction("AMDeviceSecureStartService", m_AMDeviceSecureStartService); + resolveFunction("AMDeviceSecureTransferPath", m_AMDeviceSecureTransferPath); + resolveFunction("AMDeviceSecureInstallApplication", m_AMDeviceSecureInstallApplication); + resolveFunction("AMDServiceConnectionGetSocket", m_AMDServiceConnectionGetSocket); + resolveFunction("AMDeviceUninstallApplication", m_AMDeviceUninstallApplication); + resolveFunction("AMDServiceConnectionSend", m_AMDServiceConnectionSend); + resolveFunction("AMDServiceConnectionReceive", m_AMDServiceConnectionReceive); + resolveFunction("AMDServiceConnectionInvalidate", m_AMDServiceConnectionInvalidate); + resolveFunction("AMDeviceIsAtLeastVersionOnPlatform", m_AMDeviceIsAtLeastVersionOnPlatform); + resolveFunction("AMDeviceLookupApplications", m_AMDeviceLookupApplications); + resolveFunction("AMDErrorString", m_AMDErrorString); + resolveFunction("MISCopyErrorStringForErrorCode", m_MISCopyErrorStringForErrorCode); + resolveFunction("USBMuxConnectByPort", m_USBMuxConnectByPort); #endif return true; } bool MobileDeviceLib::isLoaded() { - return lib.isLoaded(); + return m_mobileDeviceLib.isLoaded(); } QStringList MobileDeviceLib::errors() @@ -199,11 +143,13 @@ void MobileDeviceLib::setLogLevel(int i) } am_res_t MobileDeviceLib::deviceNotificationSubscribe(AMDeviceNotificationCallback callback, - unsigned int v1, unsigned int v2, void *callbackArgs, - const AMDeviceNotification **handle) + unsigned int v1, + unsigned int v2, + void *callbackArgs, + const AMDeviceNotification **handle) { if (m_AMDeviceNotificationSubscribe) - return m_AMDeviceNotificationSubscribe(callback,v1,v2,callbackArgs,handle); + return m_AMDeviceNotificationSubscribe(callback, v1, v2, callbackArgs, handle); return -1; } @@ -221,7 +167,9 @@ int MobileDeviceLib::deviceGetInterfaceType(AMDeviceRef device) return DeviceInterfaceType::UNKNOWN; } -CFPropertyListRef MobileDeviceLib::deviceCopyValue(AMDeviceRef device,CFStringRef group,CFStringRef key) +CFPropertyListRef MobileDeviceLib::deviceCopyValue(AMDeviceRef device, + CFStringRef group, + CFStringRef key) { if (m_AMDeviceCopyValue) return m_AMDeviceCopyValue(device, group, key); @@ -291,28 +239,35 @@ am_res_t MobileDeviceLib::deviceDisconnect(AMDeviceRef device) return -1; } -am_res_t MobileDeviceLib::deviceMountImage(AMDeviceRef device, CFStringRef imagePath, - CFDictionaryRef options, - AMDeviceMountImageCallback callback, - void *callbackExtraArgs) +am_res_t MobileDeviceLib::deviceMountImage(AMDeviceRef device, + CFStringRef imagePath, + CFDictionaryRef options, + AMDeviceMountImageCallback callback, + void *callbackExtraArgs) { if (m_AMDeviceMountImage) return m_AMDeviceMountImage(device, imagePath, options, callback, callbackExtraArgs); return -1; } -am_res_t MobileDeviceLib::deviceUninstallApplication(int serviceFd, CFStringRef bundleId, - CFDictionaryRef options, - AMDeviceInstallApplicationCallback callback, - void *callbackExtraArgs) +am_res_t MobileDeviceLib::deviceUninstallApplication(int serviceFd, + CFStringRef bundleId, + CFDictionaryRef options, + AMDeviceInstallApplicationCallback callback, + void *callbackExtraArgs) { if (m_AMDeviceUninstallApplication) - return m_AMDeviceUninstallApplication(serviceFd, bundleId, options, callback, callbackExtraArgs); + return m_AMDeviceUninstallApplication(serviceFd, + bundleId, + options, + callback, + callbackExtraArgs); return -1; } -am_res_t MobileDeviceLib::deviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, - CFDictionaryRef *res) +am_res_t MobileDeviceLib::deviceLookupApplications(AMDeviceRef device, + CFDictionaryRef options, + CFDictionaryRef *res) { if (m_AMDeviceLookupApplications) return m_AMDeviceLookupApplications(device, options, res); @@ -342,7 +297,7 @@ am_res_t MobileDeviceLib::connectByPort(unsigned int connectionId, int port, Ser void MobileDeviceLib::addError(const QString &msg) { - qDebug() << "MobileDeviceLib ERROR:" << msg; + qCWarning(loggingCategory) << "MobileDeviceLib ERROR:" << msg; m_errors << QLatin1String("MobileDeviceLib ERROR:") << msg; } @@ -351,16 +306,25 @@ void MobileDeviceLib::addError(const char *msg) addError(QLatin1String(msg)); } -am_res_t MobileDeviceLib::deviceSecureStartService(AMDeviceRef device, CFStringRef serviceName, ServiceConnRef *fdRef) +am_res_t MobileDeviceLib::deviceSecureStartService(AMDeviceRef device, + CFStringRef serviceName, + ServiceConnRef *fdRef) { if (m_AMDeviceSecureStartService) return m_AMDeviceSecureStartService(device, serviceName, nullptr, fdRef); return 0; } -int MobileDeviceLib::deviceSecureTransferApplicationPath(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef dict, AMDeviceSecureInstallApplicationCallback callback, int args) +int MobileDeviceLib::deviceSecureTransferApplicationPath( + int zero, + AMDeviceRef device, + CFURLRef url, + CFDictionaryRef dict, + AMDeviceSecureInstallApplicationCallback callback, + int args) { int returnCode = -1; + if (m_AMDeviceSecureTransferPath) returnCode = m_AMDeviceSecureTransferPath(zero, device, url, dict, callback, args); return returnCode; @@ -381,7 +345,12 @@ int MobileDeviceLib::deviceSecureInstallApplicationBundle( return returnCode; } -int MobileDeviceLib::deviceSecureInstallApplication(int zero, AMDeviceRef device, CFURLRef url, CFDictionaryRef options, AMDeviceSecureInstallApplicationCallback callback, int arg) +int MobileDeviceLib::deviceSecureInstallApplication(int zero, + AMDeviceRef device, + CFURLRef url, + CFDictionaryRef options, + AMDeviceSecureInstallApplicationCallback callback, + int arg) { int returnCode = -1; if (m_AMDeviceSecureInstallApplication) { @@ -390,7 +359,8 @@ int MobileDeviceLib::deviceSecureInstallApplication(int zero, AMDeviceRef device return returnCode; } -int MobileDeviceLib::deviceConnectionGetSocket(ServiceConnRef ref) { +int MobileDeviceLib::deviceConnectionGetSocket(ServiceConnRef ref) +{ int fd = 0; if (m_AMDServiceConnectionGetSocket) fd = m_AMDServiceConnectionGetSocket(ref); @@ -428,4 +398,4 @@ bool MobileDeviceLib::deviceIsAtLeastVersionOnPlatform(AMDeviceRef device, CFDic return false; } -} // IOS +} // namespace Ios diff --git a/src/tools/iostool/mobiledevicelib.h b/src/tools/iostool/mobiledevicelib.h index 68bca9d316d..3b1c3ed8b26 100644 --- a/src/tools/iostool/mobiledevicelib.h +++ b/src/tools/iostool/mobiledevicelib.h @@ -180,8 +180,10 @@ public: QStringList m_errors; private: - QLibrary lib; - QList deps; + template void resolveFunction(const char *functionName, T &functionPtr); + +private: + QLibrary m_mobileDeviceLib; AMDSetLogLevelPtr m_AMDSetLogLevel; AMDeviceNotificationSubscribePtr m_AMDeviceNotificationSubscribe; AMDeviceNotificationUnsubscribePtr m_AMDeviceNotificationUnsubscribe;