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:
Jarek Kobus
2024-07-11 13:41:45 +02:00
parent cd7b635910
commit 6b31ff2960
3 changed files with 64 additions and 34 deletions

View File

@@ -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;

View File

@@ -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())

View File

@@ -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,