forked from qt-creator/qt-creator
iOS: Create single instance of mobile device library wrapper
Task-number: QTCREATORBUG-24672 Change-Id: I30f0022735409dbbd03b6bdadf7138ff6294b131 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -61,7 +61,8 @@ void GdbRunner::run()
|
|||||||
}
|
}
|
||||||
m_iosTool->outFile.flush();
|
m_iosTool->outFile.flush();
|
||||||
}
|
}
|
||||||
close(m_conn->sockfd);
|
MobileDeviceLib::instance().serviceConnectionInvalidate(m_conn);
|
||||||
|
m_conn = nullptr;
|
||||||
m_iosTool->doExit();
|
m_iosTool->doExit();
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
@@ -77,12 +77,13 @@ static const QString DebugServiceName = "com.apple.debugserver";
|
|||||||
static const QString DebugSecureServiceName = "com.apple.debugserver.DVTSecureSocketProxy";
|
static const QString DebugSecureServiceName = "com.apple.debugserver.DVTSecureSocketProxy";
|
||||||
|
|
||||||
|
|
||||||
static QString mobileDeviceErrorString(MobileDeviceLib *lib, am_res_t code)
|
static QString mobileDeviceErrorString(am_res_t code)
|
||||||
{
|
{
|
||||||
QString s = QStringLiteral("Unknown error (0x%08x)").arg(code);
|
QString s = QStringLiteral("Unknown error (0x%08x)").arg(code);
|
||||||
|
|
||||||
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
// AMDErrors, 0x0, 0xe8000001-0xe80000db
|
// AMDErrors, 0x0, 0xe8000001-0xe80000db
|
||||||
if (char *ptr = lib->errorString(code)) {
|
if (char *ptr = mLib.errorString(code)) {
|
||||||
CFStringRef key = QString::fromLatin1(ptr).toCFString();
|
CFStringRef key = QString::fromLatin1(ptr).toCFString();
|
||||||
|
|
||||||
CFURLRef url = QUrl::fromLocalFile(
|
CFURLRef url = QUrl::fromLocalFile(
|
||||||
@@ -98,7 +99,7 @@ static QString mobileDeviceErrorString(MobileDeviceLib *lib, am_res_t code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(key);
|
CFRelease(key);
|
||||||
} else if (CFStringRef str = lib->misErrorStringForErrorCode(code)) {
|
} else if (CFStringRef str = mLib.misErrorStringForErrorCode(code)) {
|
||||||
// MIS errors, 0xe8008001-0xe800801e
|
// MIS errors, 0xe8008001-0xe800801e
|
||||||
s = QString::fromCFString(str);
|
s = QString::fromCFString(str);
|
||||||
CFRelease(str);
|
CFRelease(str);
|
||||||
@@ -254,8 +255,6 @@ public:
|
|||||||
bool expectGdbOkReply(ServiceConnRef conn);
|
bool expectGdbOkReply(ServiceConnRef conn);
|
||||||
bool startServiceSecure(const QString &serviceName, ServiceConnRef &conn);
|
bool startServiceSecure(const QString &serviceName, ServiceConnRef &conn);
|
||||||
|
|
||||||
MobileDeviceLib *lib();
|
|
||||||
|
|
||||||
AMDeviceRef device;
|
AMDeviceRef device;
|
||||||
int progressBase;
|
int progressBase;
|
||||||
int unexpectedChars;
|
int unexpectedChars;
|
||||||
@@ -301,7 +300,6 @@ private:
|
|||||||
QHash<QString, AMDeviceRef> m_devices;
|
QHash<QString, AMDeviceRef> m_devices;
|
||||||
QMultiHash<QString, PendingDeviceLookup *> m_pendingLookups;
|
QMultiHash<QString, PendingDeviceLookup *> m_pendingLookups;
|
||||||
AMDeviceNotificationRef m_notification;
|
AMDeviceNotificationRef m_notification;
|
||||||
MobileDeviceLib m_lib;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DevInfoSession: public CommandSession {
|
class DevInfoSession: public CommandSession {
|
||||||
@@ -472,14 +470,8 @@ IosDeviceManagerPrivate::IosDeviceManagerPrivate (IosDeviceManager *q) : q(q), m
|
|||||||
|
|
||||||
bool IosDeviceManagerPrivate::watchDevices()
|
bool IosDeviceManagerPrivate::watchDevices()
|
||||||
{
|
{
|
||||||
if (!m_lib.load())
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
addError(QLatin1String("Error loading MobileDevice.framework"));
|
am_res_t e = mLib.deviceNotificationSubscribe(&deviceNotificationCallback, 0, 0,
|
||||||
if (!m_lib.errors().isEmpty()) {
|
|
||||||
foreach (const QString &msg, m_lib.errors())
|
|
||||||
addError(msg);
|
|
||||||
}
|
|
||||||
m_lib.setLogLevel(5);
|
|
||||||
am_res_t e = m_lib.deviceNotificationSubscribe(&deviceNotificationCallback, 0, 0,
|
|
||||||
0, &m_notification);
|
0, &m_notification);
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
addError(QLatin1String("AMDeviceNotificationSubscribe failed"));
|
addError(QLatin1String("AMDeviceNotificationSubscribe failed"));
|
||||||
@@ -508,7 +500,8 @@ void IosDeviceManagerPrivate::requestDeviceInfo(const QString &deviceId, int tim
|
|||||||
|
|
||||||
QStringList IosDeviceManagerPrivate::errors()
|
QStringList IosDeviceManagerPrivate::errors()
|
||||||
{
|
{
|
||||||
return m_lib.errors();
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
return mLib.errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IosDeviceManagerPrivate::addError(QString errorMsg)
|
void IosDeviceManagerPrivate::addError(QString errorMsg)
|
||||||
@@ -520,7 +513,8 @@ void IosDeviceManagerPrivate::addError(QString errorMsg)
|
|||||||
|
|
||||||
QString IosDeviceManagerPrivate::deviceId(AMDeviceRef device)
|
QString IosDeviceManagerPrivate::deviceId(AMDeviceRef device)
|
||||||
{
|
{
|
||||||
CFStringRef s = m_lib.deviceCopyDeviceIdentifier(device);
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
CFStringRef s = mLib.deviceCopyDeviceIdentifier(device);
|
||||||
// remove dashes as a hotfix for QTCREATORBUG-21291
|
// remove dashes as a hotfix for QTCREATORBUG-21291
|
||||||
const auto id = QString::fromCFString(s).remove('-');
|
const auto id = QString::fromCFString(s).remove('-');
|
||||||
if (s) CFRelease(s);
|
if (s) CFRelease(s);
|
||||||
@@ -532,7 +526,8 @@ void IosDeviceManagerPrivate::addDevice(AMDeviceRef device)
|
|||||||
const QString devId = deviceId(device);
|
const QString devId = deviceId(device);
|
||||||
CFRetain(device);
|
CFRetain(device);
|
||||||
|
|
||||||
DeviceInterfaceType interfaceType = static_cast<DeviceInterfaceType>(lib()->deviceGetInterfaceType(device));
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
DeviceInterfaceType interfaceType = static_cast<DeviceInterfaceType>(mLib.deviceGetInterfaceType(device));
|
||||||
if (interfaceType == DeviceInterfaceType::UNKNOWN) {
|
if (interfaceType == DeviceInterfaceType::UNKNOWN) {
|
||||||
if (debugAll)
|
if (debugAll)
|
||||||
qDebug() << "Skipping device." << devId << "Interface type: Unknown.";
|
qDebug() << "Skipping device." << devId << "Interface type: Unknown.";
|
||||||
@@ -603,11 +598,6 @@ void IosDeviceManagerPrivate::checkPendingLookups()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileDeviceLib *IosDeviceManagerPrivate::lib()
|
|
||||||
{
|
|
||||||
return &m_lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IosDeviceManagerPrivate::didTransferApp(const QString &bundlePath, const QString &deviceId,
|
void IosDeviceManagerPrivate::didTransferApp(const QString &bundlePath, const QString &deviceId,
|
||||||
IosDeviceManager::OpStatus status)
|
IosDeviceManager::OpStatus status)
|
||||||
{
|
{
|
||||||
@@ -782,8 +772,9 @@ void IosDeviceManagerPrivate::stopGdbServer(ServiceConnRef conn, int phase)
|
|||||||
{
|
{
|
||||||
CommandSession session((QString()));
|
CommandSession session((QString()));
|
||||||
QMutexLocker l(&m_sendMutex);
|
QMutexLocker l(&m_sendMutex);
|
||||||
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
if (phase == 0)
|
if (phase == 0)
|
||||||
lib()->serviceConnectionSend(conn, "\x03", 1);
|
mLib.serviceConnectionSend(conn, "\x03", 1);
|
||||||
else
|
else
|
||||||
session.sendGdbCommand(conn, "k", 1);
|
session.sendGdbCommand(conn, "k", 1);
|
||||||
}
|
}
|
||||||
@@ -801,26 +792,27 @@ bool CommandSession::connectDevice()
|
|||||||
if (!device)
|
if (!device)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (am_res_t error1 = lib()->deviceConnect(device)) {
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
if (am_res_t error1 = mLib.deviceConnect(device)) {
|
||||||
addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceConnect returned %2 (0x%3)")
|
addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceConnect returned %2 (0x%3)")
|
||||||
.arg(deviceId).arg(mobileDeviceErrorString(lib(), error1)).arg(error1));
|
.arg(deviceId).arg(mobileDeviceErrorString(error1)).arg(error1));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (lib()->deviceIsPaired(device) == 0) { // not paired
|
if (mLib.deviceIsPaired(device) == 0) { // not paired
|
||||||
if (am_res_t error = lib()->devicePair(device)) {
|
if (am_res_t error = mLib.devicePair(device)) {
|
||||||
addError(QString::fromLatin1("connectDevice %1 failed, AMDevicePair returned %2 (0x%3)")
|
addError(QString::fromLatin1("connectDevice %1 failed, AMDevicePair returned %2 (0x%3)")
|
||||||
.arg(deviceId).arg(mobileDeviceErrorString(lib(), error)).arg(error));
|
.arg(deviceId).arg(mobileDeviceErrorString(error)).arg(error));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (am_res_t error2 = lib()->deviceValidatePairing(device)) {
|
if (am_res_t error2 = mLib.deviceValidatePairing(device)) {
|
||||||
addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceValidatePairing returned %2 (0x%3)")
|
addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceValidatePairing returned %2 (0x%3)")
|
||||||
.arg(deviceId).arg(mobileDeviceErrorString(lib(), error2)).arg(error2));
|
.arg(deviceId).arg(mobileDeviceErrorString(error2)).arg(error2));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (am_res_t error3 = lib()->deviceStartSession(device)) {
|
if (am_res_t error3 = mLib.deviceStartSession(device)) {
|
||||||
addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceStartSession returned %2 (0x%3)")
|
addError(QString::fromLatin1("connectDevice %1 failed, AMDeviceStartSession returned %2 (0x%3)")
|
||||||
.arg(deviceId).arg(mobileDeviceErrorString(lib(), error3)).arg(error3));
|
.arg(deviceId).arg(mobileDeviceErrorString(error3)).arg(error3));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -828,14 +820,15 @@ bool CommandSession::connectDevice()
|
|||||||
|
|
||||||
bool CommandSession::disconnectDevice()
|
bool CommandSession::disconnectDevice()
|
||||||
{
|
{
|
||||||
if (am_res_t error = lib()->deviceStopSession(device)) {
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
if (am_res_t error = mLib.deviceStopSession(device)) {
|
||||||
addError(QString::fromLatin1("stopSession %1 failed, AMDeviceStopSession returned %2 (0x%3)")
|
addError(QString::fromLatin1("stopSession %1 failed, AMDeviceStopSession returned %2 (0x%3)")
|
||||||
.arg(deviceId).arg(mobileDeviceErrorString(lib(), error)).arg(error));
|
.arg(deviceId).arg(mobileDeviceErrorString(error)).arg(error));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (am_res_t error = lib()->deviceDisconnect(device)) {
|
if (am_res_t error = mLib.deviceDisconnect(device)) {
|
||||||
addError(QString::fromLatin1("disconnectDevice %1 failed, AMDeviceDisconnect returned %2 (0x%3)")
|
addError(QString::fromLatin1("disconnectDevice %1 failed, AMDeviceDisconnect returned %2 (0x%3)")
|
||||||
.arg(deviceId).arg(mobileDeviceErrorString(lib(), error)).arg(error));
|
.arg(deviceId).arg(mobileDeviceErrorString(error)).arg(error));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -848,9 +841,10 @@ bool CommandSession::startServiceSecure(const QString &serviceName, ServiceConnR
|
|||||||
// Connect device. AMDeviceConnect + AMDeviceIsPaired + AMDeviceValidatePairing + AMDeviceStartSession
|
// Connect device. AMDeviceConnect + AMDeviceIsPaired + AMDeviceValidatePairing + AMDeviceStartSession
|
||||||
if (connectDevice()) {
|
if (connectDevice()) {
|
||||||
CFStringRef cfsService = serviceName.toCFString();
|
CFStringRef cfsService = serviceName.toCFString();
|
||||||
if (am_res_t error = lib()->deviceSecureStartService(device, cfsService, &conn)) {
|
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)")
|
addError(QString::fromLatin1("Starting(Secure) service \"%1\" on device %2 failed, AMDeviceStartSecureService returned %3 (0x%4)")
|
||||||
.arg(serviceName).arg(deviceId).arg(mobileDeviceErrorString(lib(), error)).arg(QString::number(error, 16)));
|
.arg(serviceName).arg(deviceId).arg(mobileDeviceErrorString(error)).arg(QString::number(error, 16)));
|
||||||
success = false;
|
success = false;
|
||||||
} else {
|
} else {
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
@@ -877,7 +871,9 @@ bool CommandSession::connectToPort(quint16 port, ServiceSocket *fd)
|
|||||||
ServiceSocket fileDescriptor;
|
ServiceSocket fileDescriptor;
|
||||||
if (!connectDevice())
|
if (!connectDevice())
|
||||||
return false;
|
return false;
|
||||||
if (am_res_t error = lib()->connectByPort(lib()->deviceGetConnectionID(device), htons(port), &fileDescriptor)) {
|
|
||||||
|
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")
|
addError(QString::fromLatin1("connectByPort on device %1 port %2 failed, AMDeviceStartService returned %3")
|
||||||
.arg(deviceId).arg(port).arg(error));
|
.arg(deviceId).arg(port).arg(error));
|
||||||
failure = true;
|
failure = true;
|
||||||
@@ -977,13 +973,14 @@ bool CommandSession::mountDeveloperDiskImage() {
|
|||||||
|
|
||||||
if (connectDevice()) {
|
if (connectDevice()) {
|
||||||
CFStringRef cfImgPath = imagePath.toCFString();
|
CFStringRef cfImgPath = imagePath.toCFString();
|
||||||
am_res_t result = lib()->deviceMountImage(device, cfImgPath, options, &mountCallback, 0);
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
am_res_t result = mLib.deviceMountImage(device, cfImgPath, options, &mountCallback, 0);
|
||||||
if (result == 0 || result == kAMDMobileImageMounterImageMountFailed) {
|
if (result == 0 || result == kAMDMobileImageMounterImageMountFailed) {
|
||||||
// Mounting succeeded or developer image already installed
|
// Mounting succeeded or developer image already installed
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed, AMDeviceMountImage returned %2 (0x%3)")
|
addError(QString::fromLatin1("Mount Developer Disk Image \"%1\" failed, AMDeviceMountImage returned %2 (0x%3)")
|
||||||
.arg(imagePath).arg(mobileDeviceErrorString(lib(), result)).arg(QString::number(result, 16)));
|
.arg(imagePath).arg(mobileDeviceErrorString(result)).arg(QString::number(result, 16)));
|
||||||
}
|
}
|
||||||
CFRelease(cfImgPath);
|
CFRelease(cfImgPath);
|
||||||
disconnectDevice();
|
disconnectDevice();
|
||||||
@@ -1007,16 +1004,18 @@ bool CommandSession::sendGdbCommand(ServiceConnRef conn, const char *cmd, qptrdi
|
|||||||
unsigned char checkSum = 0;
|
unsigned char checkSum = 0;
|
||||||
for (int i = 0; i < len; ++i)
|
for (int i = 0; i < len; ++i)
|
||||||
checkSum += static_cast<unsigned char>(cmd[i]);
|
checkSum += static_cast<unsigned char>(cmd[i]);
|
||||||
bool failure = lib()->serviceConnectionSend(conn, "$", 1) == 0;
|
|
||||||
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
bool failure = mLib.serviceConnectionSend(conn, "$", 1) == 0;
|
||||||
if (!failure)
|
if (!failure)
|
||||||
failure = lib()->serviceConnectionSend(conn, cmd, len) == 0;
|
failure = mLib.serviceConnectionSend(conn, cmd, len) == 0;
|
||||||
char buf[3];
|
char buf[3];
|
||||||
buf[0] = '#';
|
buf[0] = '#';
|
||||||
const char *hex = "0123456789abcdef";
|
const char *hex = "0123456789abcdef";
|
||||||
buf[1] = hex[(checkSum >> 4) & 0xF];
|
buf[1] = hex[(checkSum >> 4) & 0xF];
|
||||||
buf[2] = hex[checkSum & 0xF];
|
buf[2] = hex[checkSum & 0xF];
|
||||||
if (!failure)
|
if (!failure)
|
||||||
failure = lib()->serviceConnectionSend(conn, buf, 3) == 0;
|
failure = mLib.serviceConnectionSend(conn, buf, 3) == 0;
|
||||||
return !failure;
|
return !failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1079,8 +1078,10 @@ int CommandSession::handleChar(ServiceConnRef conn, QByteArray &res, char c, int
|
|||||||
++unexpectedChars;
|
++unexpectedChars;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status == 3 && aknowledge)
|
if (status == 3 && aknowledge) {
|
||||||
lib()->serviceConnectionSend(conn, "+", 1);
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
mLib.serviceConnectionSend(conn, "+", 1);
|
||||||
|
}
|
||||||
return status + 1;
|
return status + 1;
|
||||||
case 4:
|
case 4:
|
||||||
addError(QString::fromLatin1("gone past end in readGdbReply"));
|
addError(QString::fromLatin1("gone past end in readGdbReply"));
|
||||||
@@ -1101,8 +1102,9 @@ QByteArray CommandSession::readGdbReply(ServiceConnRef conn)
|
|||||||
int maxRetry = 10;
|
int maxRetry = 10;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
int toRead = 4;
|
int toRead = 4;
|
||||||
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
while (status < 4 && toRead > 0) {
|
while (status < 4 && toRead > 0) {
|
||||||
qptrdiff nRead = lib()->serviceConnectionReceive(conn, buf, toRead);
|
qptrdiff nRead = mLib.serviceConnectionReceive(conn, buf, toRead);
|
||||||
if (!checkRead(nRead, maxRetry))
|
if (!checkRead(nRead, maxRetry))
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
if (debugGdbServer) {
|
if (debugGdbServer) {
|
||||||
@@ -1167,22 +1169,18 @@ bool CommandSession::expectGdbOkReply(ServiceConnRef conn)
|
|||||||
return expectGdbReply(conn, QByteArray("OK"));
|
return expectGdbReply(conn, QByteArray("OK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileDeviceLib *CommandSession::lib()
|
|
||||||
{
|
|
||||||
return IosDeviceManagerPrivate::instance()->lib();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommandSession::developerDiskImagePath(QString *path, QString *signaturePath)
|
bool CommandSession::developerDiskImagePath(QString *path, QString *signaturePath)
|
||||||
{
|
{
|
||||||
if (device && path && connectDevice()) {
|
if (device && path && connectDevice()) {
|
||||||
CFPropertyListRef cfProductVersion = lib()->deviceCopyValue(device, 0, CFSTR("ProductVersion"));
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
CFPropertyListRef cfProductVersion = mLib.deviceCopyValue(device, 0, CFSTR("ProductVersion"));
|
||||||
QString versionString;
|
QString versionString;
|
||||||
if (cfProductVersion && CFGetTypeID(cfProductVersion) == CFStringGetTypeID()) {
|
if (cfProductVersion && CFGetTypeID(cfProductVersion) == CFStringGetTypeID()) {
|
||||||
versionString = QString::fromCFString(reinterpret_cast<CFStringRef>(cfProductVersion));
|
versionString = QString::fromCFString(reinterpret_cast<CFStringRef>(cfProductVersion));
|
||||||
}
|
}
|
||||||
CFRelease(cfProductVersion);
|
CFRelease(cfProductVersion);
|
||||||
|
|
||||||
CFPropertyListRef cfBuildVersion = lib()->deviceCopyValue(device, 0, CFSTR("BuildVersion"));
|
CFPropertyListRef cfBuildVersion = mLib.deviceCopyValue(device, 0, CFSTR("BuildVersion"));
|
||||||
QString buildString;
|
QString buildString;
|
||||||
if (cfBuildVersion && CFGetTypeID(cfBuildVersion) == CFStringGetTypeID()) {
|
if (cfBuildVersion && CFGetTypeID(cfBuildVersion) == CFStringGetTypeID()) {
|
||||||
buildString = QString::fromCFString(reinterpret_cast<CFStringRef>(cfBuildVersion));
|
buildString = QString::fromCFString(reinterpret_cast<CFStringRef>(cfBuildVersion));
|
||||||
@@ -1225,19 +1223,20 @@ bool AppOpSession::installApp()
|
|||||||
&kCFTypeDictionaryKeyCallBacks,
|
&kCFTypeDictionaryKeyCallBacks,
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
|
||||||
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
// Transfer bundle with secure API AMDeviceTransferApplication.
|
// Transfer bundle with secure API AMDeviceTransferApplication.
|
||||||
if (int error = lib()->deviceSecureTransferApplicationPath(0, device, bundleUrl, options,
|
if (int error = mLib.deviceSecureTransferApplicationPath(0, device, bundleUrl, options,
|
||||||
&appSecureTransferSessionCallback,0)) {
|
&appSecureTransferSessionCallback,0)) {
|
||||||
addError(QString::fromLatin1("TransferAppSession(%1,%2) failed, AMDeviceTransferApplication returned %3 (0x%4)")
|
addError(QString::fromLatin1("TransferAppSession(%1,%2) failed, AMDeviceTransferApplication returned %3 (0x%4)")
|
||||||
.arg(bundlePath, deviceId).arg(mobileDeviceErrorString(lib(), error)).arg(error));
|
.arg(bundlePath, deviceId).arg(mobileDeviceErrorString(error)).arg(error));
|
||||||
success = false;
|
success = false;
|
||||||
} else {
|
} else {
|
||||||
// App is transferred. Try installing.
|
// App is transferred. Try installing.
|
||||||
if (connectDevice()) {
|
if (connectDevice()) {
|
||||||
// Secure install app api requires device to be connected.
|
// Secure install app api requires device to be connected.
|
||||||
if (am_res_t error = lib()->deviceSecureInstallApplication(0, device, bundleUrl, options,
|
if (am_res_t error = mLib.deviceSecureInstallApplication(0, device, bundleUrl, options,
|
||||||
&appSecureTransferSessionCallback,0)) {
|
&appSecureTransferSessionCallback,0)) {
|
||||||
const QString errorString = mobileDeviceErrorString(lib(), error);
|
const QString errorString = mobileDeviceErrorString(error);
|
||||||
if (!errorString.isEmpty()) {
|
if (!errorString.isEmpty()) {
|
||||||
addError(errorString
|
addError(errorString
|
||||||
+ QStringLiteral(" (0x")
|
+ QStringLiteral(" (0x")
|
||||||
@@ -1329,7 +1328,8 @@ bool AppOpSession::runApp()
|
|||||||
CFDictionaryRef version = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
|
CFDictionaryRef version = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values,
|
||||||
2, &kCFTypeDictionaryKeyCallBacks,
|
2, &kCFTypeDictionaryKeyCallBacks,
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
bool useSecureProxy = lib()->deviceIsAtLeastVersionOnPlatform(device, version);
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
bool useSecureProxy = mLib.deviceIsAtLeastVersionOnPlatform(device, version);
|
||||||
// The debugserver service cannot be launched directly on iOS 14+
|
// The debugserver service cannot be launched directly on iOS 14+
|
||||||
// A secure proxy service sits between the actual debugserver service.
|
// A secure proxy service sits between the actual debugserver service.
|
||||||
const QString &serviceName = useSecureProxy ? DebugSecureServiceName : DebugServiceName;
|
const QString &serviceName = useSecureProxy ? DebugSecureServiceName : DebugServiceName;
|
||||||
@@ -1376,7 +1376,7 @@ bool AppOpSession::runApp()
|
|||||||
failure = true;
|
failure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFSocketNativeHandle fd = failure ? 0 : lib()->deviceConnectionGetSocket(conn);
|
CFSocketNativeHandle fd = failure ? 0 : mLib.deviceConnectionGetSocket(conn);
|
||||||
auto status = failure ? IosDeviceManager::Failure : IosDeviceManager::Success;
|
auto status = failure ? IosDeviceManager::Failure : IosDeviceManager::Success;
|
||||||
IosDeviceManagerPrivate::instance()->didStartApp(bundlePath, deviceId, status, conn, fd, this);
|
IosDeviceManagerPrivate::instance()->didStartApp(bundlePath, deviceId, status, conn, fd, this);
|
||||||
return !failure;
|
return !failure;
|
||||||
@@ -1413,7 +1413,8 @@ QString AppOpSession::appPathOnDevice()
|
|||||||
(const void**)(&lookupKeys), 1,
|
(const void**)(&lookupKeys), 1,
|
||||||
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||||
CFRelease(lookupKeys);
|
CFRelease(lookupKeys);
|
||||||
if (int err = lib()->deviceLookupApplications(device, options, &apps)) {
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
if (int err = mLib.deviceLookupApplications(device, options, &apps)) {
|
||||||
addError(QString::fromLatin1("app lookup failed, AMDeviceLookupApplications returned %1")
|
addError(QString::fromLatin1("app lookup failed, AMDeviceLookupApplications returned %1")
|
||||||
.arg(err));
|
.arg(err));
|
||||||
}
|
}
|
||||||
@@ -1475,7 +1476,8 @@ QString DevInfoSession::getStringValue(AMDevice *device,
|
|||||||
const QString &fallback)
|
const QString &fallback)
|
||||||
{
|
{
|
||||||
QString value = fallback;
|
QString value = fallback;
|
||||||
CFPropertyListRef cfValue = lib()->deviceCopyValue(device, domain, key);
|
MobileDeviceLib &mLib = MobileDeviceLib::instance();
|
||||||
|
CFPropertyListRef cfValue = mLib.deviceCopyValue(device, domain, key);
|
||||||
if (cfValue) {
|
if (cfValue) {
|
||||||
if (CFGetTypeID(cfValue) == CFStringGetTypeID())
|
if (CFGetTypeID(cfValue) == CFStringGetTypeID())
|
||||||
value = QString::fromCFString(reinterpret_cast<CFStringRef>(cfValue));
|
value = QString::fromCFString(reinterpret_cast<CFStringRef>(cfValue));
|
||||||
|
@@ -33,8 +33,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Ios {
|
namespace Ios {
|
||||||
|
MobileDeviceLib &MobileDeviceLib::instance()
|
||||||
|
{
|
||||||
|
static MobileDeviceLib lib;
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
|
||||||
MobileDeviceLib::MobileDeviceLib()
|
MobileDeviceLib::MobileDeviceLib()
|
||||||
{
|
{
|
||||||
|
if (!load())
|
||||||
|
addError(QLatin1String("Error loading MobileDevice.framework"));
|
||||||
|
if (!errors().isEmpty()) {
|
||||||
|
foreach (const QString &msg, errors())
|
||||||
|
addError(msg);
|
||||||
|
}
|
||||||
|
setLogLevel(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MobileDeviceLib::load()
|
bool MobileDeviceLib::load()
|
||||||
|
@@ -111,13 +111,17 @@ typedef bool (MDEV_API *AMDeviceIsAtLeastVersionOnPlatformPtr)(AMDeviceRef, CFDi
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MobileDeviceLib {
|
class MobileDeviceLib {
|
||||||
public :
|
|
||||||
MobileDeviceLib();
|
MobileDeviceLib();
|
||||||
|
|
||||||
bool load();
|
bool load();
|
||||||
|
|
||||||
|
public:
|
||||||
|
MobileDeviceLib( const MobileDeviceLib& ) = delete;
|
||||||
|
MobileDeviceLib &operator=( const MobileDeviceLib& ) = delete;
|
||||||
|
|
||||||
|
static MobileDeviceLib &instance();
|
||||||
|
|
||||||
bool isLoaded();
|
bool isLoaded();
|
||||||
QStringList errors();
|
QStringList errors();
|
||||||
//
|
|
||||||
|
|
||||||
void setLogLevel(int i) ;
|
void setLogLevel(int i) ;
|
||||||
am_res_t deviceNotificationSubscribe(AMDeviceNotificationCallback callback,
|
am_res_t deviceNotificationSubscribe(AMDeviceNotificationCallback callback,
|
||||||
|
Reference in New Issue
Block a user