Esempio n. 1
0
void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath)
{
    const QString targetArch = AndroidManager::targetArch(target);
    if (targetArch.isEmpty())
        return;
    const int deviceAPILevel = AndroidManager::minimumSDK(target);
    AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch);
    if (!info.isValid()) // aborted
        return;

    QString deviceSerialNumber = info.serialNumber;
    if (info.type == AndroidDeviceInfo::Emulator) {
        deviceSerialNumber = AndroidAvdManager().startAvd(info.avdname);
        if (deviceSerialNumber.isEmpty())
            Core::MessageManager::write(tr("Starting Android virtual device failed."));
    }

    QProcess *process = new QProcess();
    QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
    arguments << QLatin1String("install") << QLatin1String("-r ") << packagePath;

    connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
            process, &QObject::deleteLater);
    const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
    Core::MessageManager::write(adb + QLatin1Char(' ') + arguments.join(QLatin1Char(' ')));
    process->start(adb, arguments);
    if (!process->waitForStarted(500) && process->state() != QProcess::Running)
        delete process;
}
bool AndroidDeployQtStep::init(QList<const BuildStep *> &earlierSteps)
{
    Q_UNUSED(earlierSteps);
    m_androiddeployqtArgs.clear();

    if (AndroidManager::checkForQt51Files(project()->projectDirectory()))
        emit addOutput(tr("Found old folder \"android\" in source directory. Qt 5.2 does not use that folder by default."), ErrorOutput);

    m_targetArch = AndroidManager::targetArch(target());
    if (m_targetArch.isEmpty()) {
        emit addOutput(tr("No Android arch set by the .pro file."), ErrorOutput);
        return false;
    }

    AndroidBuildApkStep *androidBuildApkStep
        = AndroidGlobal::buildStep<AndroidBuildApkStep>(target()->activeBuildConfiguration());
    if (!androidBuildApkStep) {
        emit addOutput(tr("Cannot find the android build step."), ErrorOutput);
        return false;
    }

    int deviceAPILevel = AndroidManager::minimumSDK(target());
    AndroidConfigurations::Options options = AndroidConfigurations::None;
    if (androidBuildApkStep->deployAction() == AndroidBuildApkStep::DebugDeployment)
        options = AndroidConfigurations::FilterAndroid5;
    AndroidDeviceInfo info = earlierDeviceInfo(earlierSteps, Id);
    if (!info.isValid()) {
        info = AndroidConfigurations::showDeviceDialog(project(), deviceAPILevel, m_targetArch, options);
        m_deviceInfo = info; // Keep around for later steps
    }

    if (!info.isValid()) // aborted
        return false;

    m_avdName = info.avdname;
    m_serialNumber = info.serialNumber;

    m_appProcessBinaries.clear();
    m_libdir = QLatin1String("lib");
    if (info.cpuAbi.contains(QLatin1String("arm64-v8a")) ||
            info.cpuAbi.contains(QLatin1String("x86_64"))) {
        ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit(), ToolChain::Language::Cxx);
        if (tc && tc->targetAbi().wordWidth() == 64) {
            m_appProcessBinaries << QLatin1String("/system/bin/app_process64");
            m_libdir += QLatin1String("64");
        } else {
            m_appProcessBinaries << QLatin1String("/system/bin/app_process32");
        }
    } else {
        m_appProcessBinaries << QLatin1String("/system/bin/app_process32")
                             << QLatin1String("/system/bin/app_process");
    }

    AndroidManager::setDeviceSerialNumber(target(), m_serialNumber);

    ProjectExplorer::BuildConfiguration *bc = target()->activeBuildConfiguration();

    QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
    if (!version)
        return false;

    m_uninstallPreviousPackageRun = m_uninstallPreviousPackage;
    if (m_uninstallPreviousPackageRun)
        m_manifestName = AndroidManager::manifestPath(target());

    m_useAndroiddeployqt = version->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0);
    if (m_useAndroiddeployqt) {
        Utils::FileName tmp = AndroidManager::androidQtSupport(target())->androiddeployqtPath(target());
        if (tmp.isEmpty()) {
            emit addOutput(tr("Cannot find the androiddeployqt tool."), ErrorOutput);
            return false;
        }

        m_command = tmp.toString();
        m_workingDirectory = bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString();

        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--verbose"));
        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--output"));
        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, m_workingDirectory);
        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--no-build"));
        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--input"));
        tmp = AndroidManager::androidQtSupport(target())->androiddeployJsonPath(target());
        if (tmp.isEmpty()) {
            emit addOutput(tr("Cannot find the androiddeploy Json file."), ErrorOutput);
            return false;
        }
        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, tmp.toString());

        Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--deployment"));
        switch (androidBuildApkStep->deployAction()) {
            case AndroidBuildApkStep::MinistroDeployment:
                Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("ministro"));
                break;
            case AndroidBuildApkStep::DebugDeployment:
                Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("debug"));
                break;
            case AndroidBuildApkStep::BundleLibrariesDeployment:
                Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("bundled"));
                break;
        }
        if (androidBuildApkStep->useGradle())
            Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--gradle"));

        if (androidBuildApkStep->signPackage()) {
            // The androiddeployqt tool is not really written to do stand-alone installations.
            // This hack forces it to use the correct filename for the apk file when installing
            // as a temporary fix until androiddeployqt gets the support. Since the --sign is
            // only used to get the correct file name of the apk, its parameters are ignored.
            Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--sign"));
            Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("foo"));
            Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("bar"));
        }
    } else {
        m_uninstallPreviousPackageRun = true;
        m_command = AndroidConfigurations::currentConfig().adbToolPath().toString();
        m_apkPath = AndroidManager::androidQtSupport(target())->apkPath(target()).toString();
        m_workingDirectory = bc->buildDirectory().toString();
    }
    m_environment = bc->environment();

    m_buildDirectory = bc->buildDirectory().toString();

    m_adbPath = AndroidConfigurations::currentConfig().adbToolPath().toString();

    if (AndroidConfigurations::currentConfig().findAvd(m_avdName).isEmpty())
        AndroidConfigurations::currentConfig().startAVDAsync(m_avdName);
    return true;
}