diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index c5106c73139ae3310736ed314625bfe607d39a84..d8ef7ce318951b70b56af59cff4cf2dda4779c4d 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -364,12 +364,12 @@ FileName AndroidConfigurations::zipalignPath() const return path.appendPath(QLatin1String("tools/zipalign" QTC_HOST_EXE_SUFFIX)); } -QString AndroidConfigurations::getDeployDeviceSerialNumber(int *apiLevel) const +QString AndroidConfigurations::getDeployDeviceSerialNumber(int *apiLevel, const QString &abi) const { QVector<AndroidDeviceInfo> devices = connectedDevices(); foreach (AndroidDeviceInfo device, devices) { - if (device.sdk >= *apiLevel) { + if (device.sdk >= *apiLevel && device.cpuABI.contains(abi)) { *apiLevel = device.sdk; return device.serialNumber; } @@ -407,6 +407,7 @@ QVector<AndroidDeviceInfo> AndroidConfigurations::connectedDevices(int apiLevel) dev.serialNumber = serialNo; dev.sdk = getSDKVersion(dev.serialNumber); + dev.cpuABI = getAbis(dev.serialNumber); if (apiLevel != -1 && dev.sdk != apiLevel) continue; devices.push_back(dev); @@ -496,7 +497,7 @@ QVector<AndroidDeviceInfo> AndroidConfigurations::androidVirtualDevices() const if (line.contains(QLatin1String("Target:"))) dev.sdk = line.mid(line.lastIndexOf(QLatin1Char(' '))).remove(QLatin1Char(')')).toInt(); if (line.contains(QLatin1String("ABI:"))) - dev.cpuABI = line.mid(line.lastIndexOf(QLatin1Char(' '))).trimmed(); + dev.cpuABI = QStringList() << line.mid(line.lastIndexOf(QLatin1Char(' '))).trimmed(); } devices.push_back(dev); } @@ -590,6 +591,33 @@ int AndroidConfigurations::getSDKVersion(const QString &device) const return adbProc.readAll().trimmed().toInt(); } +QStringList AndroidConfigurations::getAbis(const QString &device) const +{ + QStringList result; + int i = 1; + while (true) { + QStringList arguments = AndroidDeviceInfo::adbSelector(device); + arguments << QLatin1String("shell") << QLatin1String("getprop"); + if (i == 1) + arguments << QLatin1String("ro.product.cpu.abi"); + else + arguments << QString::fromLatin1("ro.product.cpu.abi%1").arg(i); + + QProcess adbProc; + adbProc.start(adbToolPath().toString(), arguments); + if (!adbProc.waitForFinished(-1)) { + adbProc.kill(); + return result; + } + QString abi = QString::fromLocal8Bit(adbProc.readAll().trimmed()); + if (abi.isEmpty()) + break; + result << abi; + ++i; + } + return result; +} + QString AndroidConfigurations::bestMatch(const QString &targetAPI) const { int target = targetAPI.mid(targetAPI.lastIndexOf(QLatin1Char('-')) + 1).toInt(); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 80ac05d42b159c3df7527f8c8dd4f8f587ee2455..21cf46db5bdeb225a7ac42a22367d20d594a733f 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -32,6 +32,7 @@ #include <QObject> #include <QString> +#include <QStringList> #include <QVector> #include <projectexplorer/abi.h> #include <utils/fileutils.h> @@ -63,7 +64,7 @@ public: struct AndroidDeviceInfo { QString serialNumber; - QString cpuABI; + QStringList cpuABI; int sdk; static QStringList adbSelector(const QString &serialNumber); @@ -90,7 +91,7 @@ public: Utils::FileName zipalignPath() const; Utils::FileName stripPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const; Utils::FileName readelfPath(ProjectExplorer::Abi::Architecture architecture, const QString &ndkToolChainVersion) const; - QString getDeployDeviceSerialNumber(int *apiLevel) const; + QString getDeployDeviceSerialNumber(int *apiLevel, const QString &abi) const; bool createAVD(const QString &target, const QString &name, int sdcardSize) const; bool removeAVD(const QString &name) const; QVector<AndroidDeviceInfo> connectedDevices(int apiLevel = -1) const; @@ -122,6 +123,7 @@ private: void save(); int getSDKVersion(const QString &device) const; + QStringList getAbis(const QString &device) const; void updateAvailablePlatforms(); diff --git a/src/plugins/android/androiddeploystep.cpp b/src/plugins/android/androiddeploystep.cpp index af4260f5f3e7a4bf910db6a723b2a63e631cf8f7..17a2627730212cc39d7aae52a937f50cc847bee2 100644 --- a/src/plugins/android/androiddeploystep.cpp +++ b/src/plugins/android/androiddeploystep.cpp @@ -89,10 +89,11 @@ bool AndroidDeployStep::init() { m_packageName = AndroidManager::packageName(target()); const QString targetSDK = AndroidManager::targetSDK(target()); + const QString targetArch = AndroidManager::targetArch(target()); writeOutput(tr("Please wait, searching for a suitable device for target:%1.").arg(targetSDK)); m_deviceAPILevel = targetSDK.mid(targetSDK.indexOf(QLatin1Char('-')) + 1).toInt(); - m_deviceSerialNumber = AndroidConfigurations::instance().getDeployDeviceSerialNumber(&m_deviceAPILevel); + m_deviceSerialNumber = AndroidConfigurations::instance().getDeployDeviceSerialNumber(&m_deviceAPILevel, targetArch); if (!m_deviceSerialNumber.length()) { m_deviceSerialNumber.clear(); raiseError(tr("Cannot deploy: no devices or emulators found for your package.")); @@ -168,9 +169,10 @@ QVariantMap AndroidDeployStep::toMap() const void AndroidDeployStep::cleanLibsOnDevice() { const QString targetSDK = AndroidManager::targetSDK(target()); + const QString targetArch = AndroidManager::targetArch(target()); int deviceAPILevel = targetSDK.mid(targetSDK.indexOf(QLatin1Char('-')) + 1).toInt(); - QString deviceSerialNumber = AndroidConfigurations::instance().getDeployDeviceSerialNumber(&deviceAPILevel); + QString deviceSerialNumber = AndroidConfigurations::instance().getDeployDeviceSerialNumber(&deviceAPILevel, targetArch); if (!deviceSerialNumber.length()) { Core::MessageManager::instance()->printToOutputPane(tr("Could not run adb. No device found."), Core::MessageManager::NoModeSwitch); return; diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index dcb7ddc5c67bca54b5c2fede81d5e6bc086a1695..c701d7ea955ffbaca0c7277cf57d968a4d218c80 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -310,6 +310,17 @@ bool AndroidManager::setTargetSDK(ProjectExplorer::Target *target, const QString return true; } +QString AndroidManager::targetArch(ProjectExplorer::Target *target) +{ + Qt4ProjectManager::Qt4Project *pro = qobject_cast<Qt4ProjectManager::Qt4Project *>(target->project()); + if (!pro) + return QString(); + Qt4ProjectManager::Qt4ProFileNode *node = pro->rootQt4ProjectNode(); + if (!node) + return QString(); + return node->singleVariableValue(Qt4ProjectManager::AndroidArchVar); +} + QIcon AndroidManager::highDpiIcon(ProjectExplorer::Target *target) { return icon(target, HighDPI); diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 1671108e997a267de207ce0553a2769d9fbd07b2..0f6b3d229388f05c92ce1767619d75bc0eb3b88c 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -90,6 +90,8 @@ public: static QString targetSDK(ProjectExplorer::Target *target); static bool setTargetSDK(ProjectExplorer::Target *target, const QString &sdk); + static QString targetArch(ProjectExplorer::Target *target); + static Utils::FileName dirPath(ProjectExplorer::Target *target); static Utils::FileName manifestPath(ProjectExplorer::Target *target); static Utils::FileName libsPath(ProjectExplorer::Target *target);