summaryrefslogtreecommitdiff
path: root/src/plugins/android/androidconfigurations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/android/androidconfigurations.cpp')
-rw-r--r--src/plugins/android/androidconfigurations.cpp135
1 files changed, 73 insertions, 62 deletions
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index 292fe361da..87f2d8b60e 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -27,7 +27,6 @@
#include "androidconstants.h"
#include "androidtoolchain.h"
#include "androiddevice.h"
-#include "androidgdbserverkitinformation.h"
#include "androidmanager.h"
#include "androidqtversion.h"
#include "androiddevicedialog.h"
@@ -140,7 +139,7 @@ namespace {
SynchronousProcess proc;
proc.setProcessChannelMode(QProcess::MergedChannels);
proc.setTimeoutS(30);
- SynchronousProcessResponse response = proc.runBlocking(executable, QStringList(shell));
+ SynchronousProcessResponse response = proc.runBlocking({executable, {shell}});
if (response.result != SynchronousProcessResponse::Finished)
return true;
return !response.allOutput().contains("x86-64");
@@ -364,11 +363,9 @@ FilePath AndroidConfig::aaptToolPath() const
return aaptToolPath.pathAppended(toolPath);
}
-FilePath AndroidConfig::clangPath() const
+FilePath AndroidConfig::toolchainPath() const
{
- const FilePath clangPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/");
- const FilePath oldNdkClangPath = m_ndkLocation.pathAppended("toolchains/llvm-3.6/prebuilt/");
- const QVector<FilePath> clangSearchPaths{clangPath, oldNdkClangPath};
+ const FilePath toolchainPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/");
// detect toolchain host
QStringList hostPatterns;
@@ -385,18 +382,23 @@ FilePath AndroidConfig::clangPath() const
default: /* unknown host */ return FilePath();
}
- for (const FilePath &path : clangSearchPaths) {
- QDirIterator iter(path.toString(), hostPatterns, QDir::Dirs);
- if (iter.hasNext()) {
- iter.next();
- return path.pathAppended(iter.fileName())
- .pathAppended(HostOsInfo::withExecutableSuffix("bin/clang"));
- }
+ QDirIterator iter(toolchainPath.toString(), hostPatterns, QDir::Dirs);
+ if (iter.hasNext()) {
+ iter.next();
+ return toolchainPath.pathAppended(iter.fileName());
}
return {};
}
+FilePath AndroidConfig::clangPath() const
+{
+ const FilePath path = toolchainPath();
+ if (path.isEmpty())
+ return {};
+ return path.pathAppended(HostOsInfo::withExecutableSuffix("bin/clang"));
+}
+
FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const
{
const FilePath path = m_ndkLocation.pathAppended(
@@ -429,20 +431,20 @@ FilePath AndroidConfig::keytoolPath() const
QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const
{
- return connectedDevices(adbToolPath().toString(), error);
+ return connectedDevices(adbToolPath(), error);
}
-QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToolPath, QString *error)
+QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const FilePath &adbToolPath, QString *error)
{
QVector<AndroidDeviceInfo> devices;
SynchronousProcess adbProc;
adbProc.setTimeoutS(30);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, QStringList("devices"));
+ CommandLine cmd{adbToolPath, {"devices"}};
+ SynchronousProcessResponse response = adbProc.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished) {
if (error)
- *error = QApplication::translate("AndroidConfiguration",
- "Could not run: %1")
- .arg(adbToolPath + QLatin1String(" devices"));
+ *error = QApplication::translate("AndroidConfiguration", "Could not run: %1")
+ .arg(cmd.toUserOutput());
return devices;
}
QStringList adbDevs = response.allOutput().split('\n', QString::SkipEmptyParts);
@@ -485,7 +487,7 @@ QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToo
if (devices.isEmpty() && error)
*error = QApplication::translate("AndroidConfiguration",
"No devices found in output of: %1")
- .arg(adbToolPath + QLatin1String(" devices"));
+ .arg(cmd.toUserOutput());
return devices;
}
@@ -501,33 +503,33 @@ bool AndroidConfig::isConnected(const QString &serialNumber) const
bool AndroidConfig::isBootToQt(const QString &device) const
{
- return isBootToQt(adbToolPath().toString(), device);
+ return isBootToQt(adbToolPath(), device);
}
-bool AndroidConfig::isBootToQt(const QString &adbToolPath, const QString &device)
+bool AndroidConfig::isBootToQt(const FilePath &adbToolPath, const QString &device)
{
// workaround for '????????????' serial numbers
- QStringList arguments = AndroidDeviceInfo::adbSelector(device);
- arguments << QLatin1String("shell")
- << QLatin1String("ls -l /system/bin/appcontroller || ls -l /usr/bin/appcontroller && echo Boot2Qt");
+ CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device));
+ cmd.addArg("shell");
+ cmd.addArg("ls -l /system/bin/appcontroller || ls -l /usr/bin/appcontroller && echo Boot2Qt");
SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking(cmd);
return response.result == SynchronousProcessResponse::Finished
&& response.allOutput().contains(QLatin1String("Boot2Qt"));
}
-QString AndroidConfig::getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property)
+QString AndroidConfig::getDeviceProperty(const FilePath &adbToolPath, const QString &device, const QString &property)
{
// workaround for '????????????' serial numbers
- QStringList arguments = AndroidDeviceInfo::adbSelector(device);
- arguments << QLatin1String("shell") << QLatin1String("getprop") << property;
+ CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device));
+ cmd.addArgs({"shell", "getprop", property});
SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished)
return QString();
@@ -536,12 +538,12 @@ QString AndroidConfig::getDeviceProperty(const QString &adbToolPath, const QStri
int AndroidConfig::getSDKVersion(const QString &device) const
{
- return getSDKVersion(adbToolPath().toString(), device);
+ return getSDKVersion(adbToolPath(), device);
}
-int AndroidConfig::getSDKVersion(const QString &adbToolPath, const QString &device)
+int AndroidConfig::getSDKVersion(const FilePath &adbToolPath, const QString &device)
{
- QString tmp = getDeviceProperty(adbToolPath, device, QLatin1String("ro.build.version.sdk"));
+ QString tmp = getDeviceProperty(adbToolPath, device, "ro.build.version.sdk");
if (tmp.isEmpty())
return -1;
return tmp.trimmed().toInt();
@@ -612,7 +614,7 @@ QString AndroidConfig::getProductModel(const QString &device) const
if (m_serialNumberToDeviceName.contains(device))
return m_serialNumberToDeviceName.value(device);
- QString model = getDeviceProperty(adbToolPath().toString(), device, QLatin1String("ro.product.model")).trimmed();
+ QString model = getDeviceProperty(adbToolPath(), device, "ro.product.model").trimmed();
if (model.isEmpty())
return device;
@@ -623,18 +625,18 @@ QString AndroidConfig::getProductModel(const QString &device) const
QStringList AndroidConfig::getAbis(const QString &device) const
{
- return getAbis(adbToolPath().toString(), device);
+ return getAbis(adbToolPath(), device);
}
-QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &device)
+QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &device)
{
QStringList result;
// First try via ro.product.cpu.abilist
QStringList arguments = AndroidDeviceInfo::adbSelector(device);
- arguments << QLatin1String("shell") << QLatin1String("getprop") << QLatin1String("ro.product.cpu.abilist");
+ arguments << "shell" << "getprop" << "ro.product.cpu.abilist";
SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking({adbToolPath, arguments});
if (response.result != SynchronousProcessResponse::Finished)
return result;
@@ -656,7 +658,7 @@ QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &de
SynchronousProcess abiProc;
abiProc.setTimeoutS(10);
- SynchronousProcessResponse abiResponse = abiProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse abiResponse = abiProc.runBlocking({adbToolPath, arguments});
if (abiResponse.result != SynchronousProcessResponse::Finished)
return result;
@@ -733,22 +735,26 @@ FilePath AndroidConfig::ndkLocation() const
return m_ndkLocation;
}
-static inline QString gdbServerArch(const Abi &abi)
+static inline QString gdbServerArch(const QString &androidAbi)
{
- switch (abi.architecture()) {
- case Abi::X86Architecture:
- return abi.wordWidth() == 64 ? QString{"x86_64"} : QString{"x86"};
- case Abi::ArmArchitecture:
- return abi.wordWidth() == 64 ? QString{"arm64"} : QString{"arm"};
- default: return {};
- };
+ if (androidAbi == "arm64-v8a") {
+ return QString("arm64");
+ } else if (androidAbi == "armeabi-v7a") {
+ return QString("arm");
+ } else if (androidAbi == "x86_64") {
+ return QString("x86_64");
+ } else if (androidAbi == "x86") {
+ return QString("x86");
+ } else {
+ return {};
+ }
}
-FilePath AndroidConfig::gdbServer(const ProjectExplorer::Abi &abi) const
+FilePath AndroidConfig::gdbServer(const QString &androidAbi) const
{
const FilePath path = AndroidConfigurations::currentConfig().ndkLocation()
.pathAppended(QString("prebuilt/android-%1/gdbserver/gdbserver")
- .arg(gdbServerArch(abi)));
+ .arg(gdbServerArch(androidAbi)));
if (path.exists())
return path;
return {};
@@ -875,16 +881,21 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
}
AndroidDeviceInfo AndroidConfigurations::showDeviceDialog(Project *project,
- int apiLevel, const QString &abi)
+ int apiLevel, const QStringList &abis)
{
- QString serialNumber = defaultDevice(project, abi);
- AndroidDeviceDialog dialog(apiLevel, abi, serialNumber, Core::ICore::mainWindow());
+ QString serialNumber;
+ for (const QString &abi : abis) {
+ serialNumber = defaultDevice(project, abi);
+ if (!serialNumber.isEmpty())
+ break;
+ }
+ AndroidDeviceDialog dialog(apiLevel, abis, serialNumber, Core::ICore::mainWindow());
AndroidDeviceInfo info = dialog.device();
if (dialog.saveDeviceSelection() && info.isValid()) {
const QString serialNumber = info.type == AndroidDeviceInfo::Hardware ?
info.serialNumber : info.avdname;
if (!serialNumber.isEmpty())
- AndroidConfigurations::setDefaultDevice(project, abi, serialNumber);
+ AndroidConfigurations::setDefaultDevice(project, AndroidManager::devicePreferredAbi(info.cpuAbi, abis), serialNumber);
}
return info;
}
@@ -918,7 +929,7 @@ static bool matchToolChain(const ToolChain *atc, const ToolChain *btc)
if (!atc || !btc)
return false;
- if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
+ if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID)
return false;
auto aatc = static_cast<const AndroidToolChain *>(atc);
@@ -930,7 +941,7 @@ void AndroidConfigurations::registerNewToolChains()
{
const QList<ToolChain *> existingAndroidToolChains
= ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId,
- Core::Id(Constants::ANDROID_TOOLCHAIN_ID)));
+ Core::Id(Constants::ANDROID_TOOLCHAIN_TYPEID)));
const QList<ToolChain *> newToolchains
= AndroidToolChainFactory::autodetectToolChainsForNdk(existingAndroidToolChains);
foreach (ToolChain *tc, newToolchains)
@@ -939,7 +950,7 @@ void AndroidConfigurations::registerNewToolChains()
void AndroidConfigurations::removeOldToolChains()
{
- foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_ID)))) {
+ foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_TYPEID)))) {
if (!tc->isValid())
ToolChainManager::deregisterToolChain(tc);
}
@@ -947,7 +958,7 @@ void AndroidConfigurations::removeOldToolChains()
static QVariant findOrRegisterDebugger(ToolChain *tc)
{
- const FilePath command = tc->suggestedDebugger();
+ const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi());
// check if the debugger is already registered, but ignoring the display name
const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command);
if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected()
@@ -955,7 +966,7 @@ static QVariant findOrRegisterDebugger(ToolChain *tc)
return existing->id();
// debugger not found, register a new one
Debugger::DebuggerItem debugger;
- debugger.setCommand(tc->suggestedDebugger());
+ debugger.setCommand(command);
debugger.setEngineType(Debugger::GdbEngineType);
debugger.setUnexpandedDisplayName(
AndroidConfigurations::tr("Android Debugger for %1").arg(tc->displayName()));
@@ -1016,7 +1027,7 @@ void AndroidConfigurations::updateAutomaticKitList()
const QList<ToolChain *> toolchains = ToolChainManager::toolChains([](const ToolChain *tc) {
return tc->isAutoDetected()
&& tc->isValid()
- && tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID;
+ && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID;
});
for (ToolChain *tc : toolchains) {
if (tc->language() != Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID))
@@ -1049,10 +1060,9 @@ void AndroidConfigurations::updateAutomaticKitList()
QtSupport::QtKitAspect::setQtVersion(k, qt);
DeviceKitAspect::setDevice(k, device);
Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc));
- AndroidGdbServerKitAspect::setGdbSever(k, currentConfig().gdbServer(tc->targetAbi()));
k->makeSticky();
k->setUnexpandedDisplayName(tr("Android for %1 (Clang %2)")
- .arg(static_cast<const AndroidQtVersion *>(qt)->targetArch())
+ .arg(static_cast<const AndroidQtVersion *>(qt)->androidAbis().join(","))
.arg(qt->displayName()));
k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString());
k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString());
@@ -1187,7 +1197,8 @@ void AndroidConfigurations::load()
SynchronousProcess proc;
proc.setTimeoutS(2);
proc.setProcessChannelMode(QProcess::MergedChannels);
- SynchronousProcessResponse response = proc.runBlocking(javaHomeExec.absoluteFilePath(), QStringList());
+ SynchronousProcessResponse response =
+ proc.runBlocking({javaHomeExec.absoluteFilePath(), {}});
if (response.result == SynchronousProcessResponse::Finished) {
const QString &javaHome = response.allOutput().trimmed();
if (!javaHome.isEmpty() && QFileInfo::exists(javaHome))