Android: Fix Sdk manager system environment

Android native tools fail if JAVA_HOME environment variable is
not defined

Task-number: QTCREATORBUG-19072
Change-Id: I3db910b34d9bdd9ebc9ba052b5300ecf5ef3ce15
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
Vikas Pachdha
2017-10-10 09:58:19 +02:00
parent cd575e3a76
commit 5754b7d09f
5 changed files with 43 additions and 39 deletions
@@ -56,6 +56,7 @@
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <utils/synchronousprocess.h>
#include <utils/environment.h>
#include <QApplication>
#include <QDirIterator>
@@ -1070,6 +1071,19 @@ bool AndroidConfigurations::force32bitEmulator()
return m_instance->m_force32bit;
}
QProcessEnvironment AndroidConfigurations::toolsEnvironment(const AndroidConfig &config)
{
Environment env = Environment::systemEnvironment();
Utils::FileName jdkLocation = config.openJDKLocation();
if (!jdkLocation.isEmpty()) {
env.set("JAVA_HOME", jdkLocation.toUserOutput());
Utils::FileName binPath = jdkLocation;
binPath.appendPath("bin");
env.prependOrSetPath(binPath.toUserOutput());
}
return env.toProcessEnvironment();
}
/**
* Workaround for '????????????' serial numbers
* @return ("-d") for buggy devices, ("-s", <serial no>) for normal
@@ -30,6 +30,7 @@
#include <projectexplorer/toolchain.h>
#include <QObject>
#include <QProcessEnvironment>
#include <QString>
#include <QStringList>
#include <QVector>
@@ -204,6 +205,7 @@ public:
static void removeOldToolChains();
static void updateAutomaticKitList();
static bool force32bitEmulator();
static QProcessEnvironment toolsEnvironment(const AndroidConfig &config);
signals:
void updated();
+14 -13
View File
@@ -129,13 +129,14 @@ void watcherDeleter(QFutureWatcher<void> *watcher)
Runs the \c sdkmanger tool with arguments \a args. Returns \c true if the command is
successfully executed. Output is copied into \a output. The function blocks the calling thread.
*/
static bool sdkManagerCommand(const Utils::FileName &toolPath, const QStringList &args,
static bool sdkManagerCommand(const AndroidConfig &config, const QStringList &args,
QString *output, int timeout = sdkManagerCmdTimeoutS)
{
SynchronousProcess proc;
proc.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(config));
proc.setTimeoutS(timeout);
proc.setTimeOutMessageBoxEnabled(true);
SynchronousProcessResponse response = proc.run(toolPath.toString(), args);
SynchronousProcessResponse response = proc.run(config.sdkManagerToolPath().toString(), args);
if (output)
*output = response.allOutput();
return response.result == SynchronousProcessResponse::Finished;
@@ -147,13 +148,14 @@ static bool sdkManagerCommand(const Utils::FileName &toolPath, const QStringList
to cancel signal emmitted by \a sdkManager and kill the commands. The command is also killed
after the lapse of \a timeout seconds. The function blocks the calling thread.
*/
static void sdkManagerCommand(const Utils::FileName &toolPath, const QStringList &args,
static void sdkManagerCommand(const AndroidConfig &config, const QStringList &args,
AndroidSdkManager &sdkManager, SdkCmdFutureInterface &fi,
AndroidSdkManager::OperationOutput &output, double progressQuota,
bool interruptible = true, int timeout = sdkManagerOperationTimeoutS)
{
int offset = fi.progressValue();
SynchronousProcess proc;
proc.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(config));
bool assertionFound = false;
proc.setStdErrBufferedSignalsEnabled(true);
proc.setStdOutBufferedSignalsEnabled(true);
@@ -173,7 +175,7 @@ static void sdkManagerCommand(const Utils::FileName &toolPath, const QStringList
QObject::connect(&sdkManager, &AndroidSdkManager::cancelActiveOperations,
&proc, &SynchronousProcess::terminate);
}
SynchronousProcessResponse response = proc.run(toolPath.toString(), args);
SynchronousProcessResponse response = proc.run(config.sdkManagerToolPath().toString(), args);
if (assertionFound) {
output.success = false;
output.stdOutput = response.stdOut();
@@ -769,7 +771,7 @@ void AndroidSdkManagerPrivate::reloadSdkPackages()
QString packageListing;
QStringList args({"--list", "--verbose"});
args << m_config.sdkManagerToolArgs();
if (sdkManagerCommand(m_config.sdkManagerToolPath(), args, &packageListing)) {
if (sdkManagerCommand(m_config, args, &packageListing)) {
SdkManagerOutputParser parser(m_allPackages);
parser.parsePackageListing(packageListing);
}
@@ -797,7 +799,7 @@ void AndroidSdkManagerPrivate::updateInstalled(SdkCmdFutureInterface &fi)
QStringList args("--update");
args << m_config.sdkManagerToolArgs();
if (!fi.isCanceled())
sdkManagerCommand(m_config.sdkManagerToolPath(), args, m_sdkManager, fi, result, 100);
sdkManagerCommand(m_config, args, m_sdkManager, fi, result, 100);
else
qCDebug(sdkManagerLog) << "Update: Operation cancelled before start";
@@ -826,12 +828,10 @@ void AndroidSdkManagerPrivate::update(SdkCmdFutureInterface &fi, const QStringLi
result.stdOutput = QString("%1 %2").arg(isInstall ? installTag : uninstallTag)
.arg(packagePath);
fi.reportResult(result);
if (fi.isCanceled()) {
if (fi.isCanceled())
qCDebug(sdkManagerLog) << args << "Update: Operation cancelled before start";
} else {
sdkManagerCommand(m_config.sdkManagerToolPath(), args, m_sdkManager, fi, result,
progressQuota, isInstall);
}
else
sdkManagerCommand(m_config, args, m_sdkManager, fi, result, progressQuota, isInstall);
currentProgress += progressQuota;
fi.setProgressValue(currentProgress);
if (result.stdError.isEmpty() && !result.success)
@@ -869,7 +869,7 @@ void AndroidSdkManagerPrivate::checkPendingLicense(SdkCmdFutureInterface &fi)
result.type = AndroidSdkManager::LicenseCheck;
QStringList args("--licenses");
if (!fi.isCanceled())
sdkManagerCommand(m_config.sdkManagerToolPath(), args, m_sdkManager, fi, result, 100.0);
sdkManagerCommand(m_config, args, m_sdkManager, fi, result, 100.0);
else
qCDebug(sdkManagerLog) << "Update: Operation cancelled before start";
@@ -884,6 +884,7 @@ void AndroidSdkManagerPrivate::getPendingLicense(SdkCmdFutureInterface &fi)
AndroidSdkManager::OperationOutput result;
result.type = AndroidSdkManager::LicenseWorkflow;
QtcProcess licenseCommand;
licenseCommand.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(m_config));
bool reviewingLicenses = false;
licenseCommand.setCommand(m_config.sdkManagerToolPath().toString(), {"--licenses"});
if (Utils::HostOsInfo::isWindowsHost())
@@ -987,7 +988,7 @@ void AndroidSdkManagerPrivate::parseCommonArguments(QFutureInterface<QString> &f
{
QString argumentDetails;
QString output;
sdkManagerCommand(m_config.sdkManagerToolPath(), QStringList("--help"), &output);
sdkManagerCommand(m_config, QStringList("--help"), &output);
bool foundTag = false;
for (const QString& line : output.split('\n')) {
if (fi.isCanceled())
+11 -23
View File
@@ -58,11 +58,11 @@ public:
output.
*/
static bool androidToolCommand(Utils::FileName toolPath, const QStringList &args,
const Environment &environment, QString *output)
const QProcessEnvironment &environment, QString *output)
{
QString androidToolPath = toolPath.toString();
SynchronousProcess proc;
proc.setProcessEnvironment(environment.toProcessEnvironment());
proc.setProcessEnvironment(environment);
SynchronousProcessResponse response = proc.runBlocking(androidToolPath, args);
if (response.result == SynchronousProcessResponse::Finished) {
if (output)
@@ -103,7 +103,7 @@ SdkPlatformList AndroidToolManager::availableSdkPlatforms(bool *ok) const
SdkPlatformList list;
QString targetListing;
if (androidToolCommand(m_config.androidToolPath(), QStringList({"list", "target"}),
androidToolEnvironment(), &targetListing)) {
AndroidConfigurations::toolsEnvironment(m_config), &targetListing)) {
m_parser->parseTargetListing(targetListing, m_config.sdkLocation(), list);
success = true;
} else {
@@ -124,14 +124,15 @@ void AndroidToolManager::launchAvdManager() const
QFuture<CreateAvdInfo> AndroidToolManager::createAvd(CreateAvdInfo info) const
{
return Utils::runAsync(&AndroidToolManager::createAvdImpl, info,
m_config.androidToolPath(), androidToolEnvironment());
m_config.androidToolPath(),
AndroidConfigurations::toolsEnvironment(m_config));
}
bool AndroidToolManager::removeAvd(const QString &name) const
{
SynchronousProcess proc;
proc.setTimeoutS(5);
proc.setProcessEnvironment(androidToolEnvironment().toProcessEnvironment());
proc.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(m_config));
SynchronousProcessResponse response
= proc.runBlocking(m_config.androidToolPath().toString(),
QStringList({"delete", "avd", "-n", name}));
@@ -142,27 +143,14 @@ QFuture<AndroidDeviceInfoList> AndroidToolManager::androidVirtualDevicesFuture()
{
return Utils::runAsync(&AndroidToolManager::androidVirtualDevices,
m_config.androidToolPath(), m_config.sdkLocation(),
androidToolEnvironment());
}
Environment AndroidToolManager::androidToolEnvironment() const
{
Environment env = Environment::systemEnvironment();
Utils::FileName jdkLocation = m_config.openJDKLocation();
if (!jdkLocation.isEmpty()) {
env.set(QLatin1String("JAVA_HOME"), jdkLocation.toUserOutput());
Utils::FileName binPath = jdkLocation;
binPath.appendPath(QLatin1String("bin"));
env.prependOrSetPath(binPath.toUserOutput());
}
return env;
AndroidConfigurations::toolsEnvironment(m_config));
}
CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FileName androidToolPath,
Environment env)
QProcessEnvironment env)
{
QProcess proc;
proc.setProcessEnvironment(env.toProcessEnvironment());
proc.setProcessEnvironment(env);
QStringList arguments;
arguments << QLatin1String("create") << QLatin1String("avd")
<< QLatin1String("-t") << AndroidConfig::apiLevelNameFor(info.sdkPlatform)
@@ -212,11 +200,11 @@ CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FileName and
AndroidDeviceInfoList AndroidToolManager::androidVirtualDevices(const Utils::FileName &androidTool,
const FileName &sdkLocationPath,
const Environment &environment)
const QProcessEnvironment &env)
{
AndroidDeviceInfoList devices;
QString output;
if (!androidToolCommand(androidTool, QStringList({"list", "avd"}), environment, &output))
if (!androidToolCommand(androidTool, QStringList({"list", "avd"}), env, &output))
return devices;
QStringList avds = output.split('\n');
+2 -3
View File
@@ -57,12 +57,11 @@ public:
// Helper methods
private:
Utils::Environment androidToolEnvironment() const;
static CreateAvdInfo createAvdImpl(CreateAvdInfo info, Utils::FileName androidToolPath,
Utils::Environment env);
QProcessEnvironment env);
static AndroidDeviceInfoList androidVirtualDevices(const Utils::FileName &androidTool,
const Utils::FileName &sdkLlocationPath,
const Utils::Environment &environment);
const QProcessEnvironment &env);
private:
const AndroidConfig &m_config;
std::unique_ptr<AndroidToolOutputParser> m_parser;