forked from qt-creator/qt-creator
Android: Make installQASIPackage() asynchronous
Reuse existing avd recipes and run a task tree instead. Change-Id: Ieaeb84eee299d7f75101a3076027d4185533b897 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -579,8 +579,70 @@ QWidget *AndroidDeployQtStep::createConfigWidget()
|
|||||||
Tr::tr("Qt Android Installer"),
|
Tr::tr("Qt Android Installer"),
|
||||||
FileUtils::homePath(),
|
FileUtils::homePath(),
|
||||||
Tr::tr("Android package (*.apk)"));
|
Tr::tr("Android package (*.apk)"));
|
||||||
if (!packagePath.isEmpty())
|
if (packagePath.isEmpty())
|
||||||
AndroidManager::installQASIPackage(target(), packagePath);
|
return;
|
||||||
|
|
||||||
|
// TODO: Write error messages on all the early returns below.
|
||||||
|
Target *currentTarget = target();
|
||||||
|
if (currentTarget == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QStringList appAbis = AndroidManager::applicationAbis(currentTarget);
|
||||||
|
if (appAbis.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const IDevice::ConstPtr device = DeviceKitAspect::device(currentTarget->kit());
|
||||||
|
const AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromIDevice(device.get());
|
||||||
|
if (!info.isValid()) // aborted
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Storage<QString> serialNumberStorage;
|
||||||
|
|
||||||
|
const auto onSetup = [serialNumberStorage, info] {
|
||||||
|
if (info.type == IDevice::Emulator)
|
||||||
|
return SetupResult::Continue;
|
||||||
|
if (info.serialNumber.isEmpty())
|
||||||
|
return SetupResult::StopWithError;
|
||||||
|
*serialNumberStorage = info.serialNumber;
|
||||||
|
return SetupResult::StopWithSuccess;
|
||||||
|
};
|
||||||
|
const auto onDone = [serialNumberStorage, info](DoneWith result) {
|
||||||
|
if (info.type == IDevice::Emulator && serialNumberStorage->isEmpty()) {
|
||||||
|
Core::MessageManager::writeDisrupting(Tr::tr("Starting Android virtual device failed."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return result == DoneWith::Success;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto onAdbSetup = [serialNumberStorage, packagePath](Process &process) {
|
||||||
|
const CommandLine cmd{AndroidConfig::adbToolPath(),
|
||||||
|
{AndroidDeviceInfo::adbSelector(*serialNumberStorage),
|
||||||
|
"install", "-r", packagePath.path()}};
|
||||||
|
process.setCommand(cmd);
|
||||||
|
};
|
||||||
|
const auto onAdbDone = [](const Process &process, DoneWith result) {
|
||||||
|
if (result == DoneWith::Success) {
|
||||||
|
Core::MessageManager::writeSilently(
|
||||||
|
Tr::tr("Android package installation finished with success."));
|
||||||
|
} else {
|
||||||
|
Core::MessageManager::writeDisrupting(Tr::tr("Android package installation failed.")
|
||||||
|
+ '\n' + process.cleanedStdErr());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Group recipe {
|
||||||
|
serialNumberStorage,
|
||||||
|
Group {
|
||||||
|
onGroupSetup(onSetup),
|
||||||
|
AndroidAvdManager::startAvdRecipe(info.avdName, serialNumberStorage),
|
||||||
|
onGroupDone(onDone)
|
||||||
|
},
|
||||||
|
ProcessTask(onAdbSetup, onAdbDone)
|
||||||
|
};
|
||||||
|
|
||||||
|
TaskTreeRunner *runner = new TaskTreeRunner;
|
||||||
|
runner->setParent(currentTarget);
|
||||||
|
runner->start(recipe);
|
||||||
});
|
});
|
||||||
|
|
||||||
using namespace Layouting;
|
using namespace Layouting;
|
||||||
|
@@ -583,36 +583,6 @@ QString androidNameForApiLevel(int x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installQASIPackage(Target *target, const FilePath &packagePath)
|
|
||||||
{
|
|
||||||
const QStringList appAbis = AndroidManager::applicationAbis(target);
|
|
||||||
if (appAbis.isEmpty())
|
|
||||||
return;
|
|
||||||
const IDevice::ConstPtr device = DeviceKitAspect::device(target->kit());
|
|
||||||
AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromIDevice(device.get());
|
|
||||||
if (!info.isValid()) // aborted
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString deviceSerialNumber = info.serialNumber;
|
|
||||||
if (info.type == IDevice::Emulator) {
|
|
||||||
deviceSerialNumber = AndroidAvdManager::startAvd(info.avdName);
|
|
||||||
if (deviceSerialNumber.isEmpty())
|
|
||||||
MessageManager::writeDisrupting(Tr::tr("Starting Android virtual device failed."));
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
|
|
||||||
arguments << "install" << "-r " << packagePath.path();
|
|
||||||
QString error;
|
|
||||||
Process *process = startAdbProcess(arguments, &error);
|
|
||||||
if (process) {
|
|
||||||
// TODO: Potential leak when the process is still running on Creator shutdown.
|
|
||||||
QObject::connect(process, &Process::done, process, &QObject::deleteLater);
|
|
||||||
} else {
|
|
||||||
MessageManager::writeDisrupting(
|
|
||||||
Tr::tr("Android package installation failed.\n%1").arg(error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkKeystorePassword(const FilePath &keystorePath, const QString &keystorePasswd)
|
bool checkKeystorePassword(const FilePath &keystorePath, const QString &keystorePasswd)
|
||||||
{
|
{
|
||||||
if (keystorePasswd.isEmpty())
|
if (keystorePasswd.isEmpty())
|
||||||
|
@@ -72,8 +72,6 @@ bool skipInstallationAndPackageSteps(const ProjectExplorer::Target *target);
|
|||||||
|
|
||||||
QString androidNameForApiLevel(int x);
|
QString androidNameForApiLevel(int x);
|
||||||
|
|
||||||
void installQASIPackage(ProjectExplorer::Target *target, const Utils::FilePath &packagePath);
|
|
||||||
|
|
||||||
bool checkKeystorePassword(const Utils::FilePath &keystorePath,
|
bool checkKeystorePassword(const Utils::FilePath &keystorePath,
|
||||||
const QString &keystorePasswd);
|
const QString &keystorePasswd);
|
||||||
bool checkCertificatePassword(const Utils::FilePath &keystorePath,
|
bool checkCertificatePassword(const Utils::FilePath &keystorePath,
|
||||||
|
Reference in New Issue
Block a user