Commit c842d83f authored by Daniel Teske's avatar Daniel Teske
Browse files

Android: Check target architecture before deploying to device



Change-Id: I2d05f98cb6c390fb84186929fdf4152cc07d8965
Reviewed-by: default avatarEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
parent c45e4e61
......@@ -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();
......
......@@ -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();
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment