diff options
Diffstat (limited to 'src/plugins/android')
57 files changed, 1084 insertions, 1524 deletions
diff --git a/src/plugins/android/CMakeLists.txt b/src/plugins/android/CMakeLists.txt new file mode 100644 index 0000000000..36bde749a9 --- /dev/null +++ b/src/plugins/android/CMakeLists.txt @@ -0,0 +1,52 @@ +add_qtc_plugin(Android + DEPENDS QtcSsh QmlDebug Qt5::Xml + PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport + SOURCES + adbcommandswidget.cpp adbcommandswidget.h adbcommandswidget.ui + addnewavddialog.ui + android.qrc + android_global.h + androidavdmanager.cpp androidavdmanager.h + androidbuildapkstep.cpp androidbuildapkstep.h + androidbuildapkwidget.cpp androidbuildapkwidget.h + androidconfigurations.cpp androidconfigurations.h + androidconstants.h + androidcreatekeystorecertificate.cpp androidcreatekeystorecertificate.h androidcreatekeystorecertificate.ui + androiddebugsupport.cpp androiddebugsupport.h + androiddeployqtstep.cpp androiddeployqtstep.h + androiddevice.cpp androiddevice.h + androiddevicedialog.cpp androiddevicedialog.h androiddevicedialog.ui + androiderrormessage.cpp androiderrormessage.h + androidextralibrarylistmodel.cpp androidextralibrarylistmodel.h + androidgdbserverkitinformation.cpp androidgdbserverkitinformation.h + androidglobal.h + androidmanager.cpp androidmanager.h + androidmanifestdocument.cpp androidmanifestdocument.h + androidmanifesteditor.cpp androidmanifesteditor.h + androidmanifesteditorfactory.cpp androidmanifesteditorfactory.h + androidmanifesteditorwidget.cpp androidmanifesteditorwidget.h + androidpackageinstallationstep.cpp androidpackageinstallationstep.h + androidplugin.cpp androidplugin.h + androidpotentialkit.cpp androidpotentialkit.h + androidqmltoolingsupport.cpp androidqmltoolingsupport.h + androidqtversion.cpp androidqtversion.h + androidrunconfiguration.cpp androidrunconfiguration.h + androidruncontrol.cpp androidruncontrol.h + androidrunner.cpp androidrunner.h + androidrunnerworker.cpp androidrunnerworker.h + androidsdkmanager.cpp androidsdkmanager.h + androidsdkmanagerwidget.cpp androidsdkmanagerwidget.h androidsdkmanagerwidget.ui + androidsdkmodel.cpp androidsdkmodel.h + androidsdkpackage.cpp androidsdkpackage.h + androidsettingspage.cpp androidsettingspage.h + androidsettingswidget.cpp androidsettingswidget.h androidsettingswidget.ui + androidsignaloperation.cpp androidsignaloperation.h + androidtoolchain.cpp androidtoolchain.h + androidtoolmanager.cpp androidtoolmanager.h + avddialog.cpp avddialog.h + certificatesmodel.cpp certificatesmodel.h + createandroidmanifestwizard.cpp createandroidmanifestwizard.h + javaeditor.cpp javaeditor.h + javaindenter.cpp javaindenter.h + javaparser.cpp javaparser.h +) diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro index e48edd2fee..f0a952c622 100644 --- a/src/plugins/android/android.pro +++ b/src/plugins/android/android.pro @@ -19,12 +19,10 @@ HEADERS += \ androidrunner.h \ androidrunnerworker.h \ androiddebugsupport.h \ - androidqtversionfactory.h \ androidqtversion.h \ androidcreatekeystorecertificate.h \ javaparser.h \ androidplugin.h \ - androiddevicefactory.h \ androiddevice.h \ androidgdbserverkitinformation.h \ androidqmltoolingsupport.h \ @@ -52,8 +50,7 @@ HEADERS += \ androidsdkmanagerwidget.h \ androidpackageinstallationstep.h \ androidextralibrarylistmodel.h \ - createandroidmanifestwizard.h \ - androidrunenvironmentaspect.h + createandroidmanifestwizard.h SOURCES += \ androidconfigurations.cpp \ @@ -67,12 +64,10 @@ SOURCES += \ androidrunner.cpp \ androidrunnerworker.cpp \ androiddebugsupport.cpp \ - androidqtversionfactory.cpp \ androidqtversion.cpp \ androidcreatekeystorecertificate.cpp \ javaparser.cpp \ androidplugin.cpp \ - androiddevicefactory.cpp \ androiddevice.cpp \ androidgdbserverkitinformation.cpp \ androidqmltoolingsupport.cpp \ @@ -99,15 +94,13 @@ SOURCES += \ androidsdkmanagerwidget.cpp \ androidpackageinstallationstep.cpp \ androidextralibrarylistmodel.cpp \ - createandroidmanifestwizard.cpp \ - androidrunenvironmentaspect.cpp + createandroidmanifestwizard.cpp FORMS += \ androidsettingswidget.ui \ addnewavddialog.ui \ androidcreatekeystorecertificate.ui \ androiddevicedialog.ui \ - androidbuildapkwidget.ui \ adbcommandswidget.ui \ androidsdkmanagerwidget.ui diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index 912bca631e..1c6ed28a41 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -36,7 +36,6 @@ Project { "androidbuildapkstep.h", "androidbuildapkwidget.cpp", "androidbuildapkwidget.h", - "androidbuildapkwidget.ui", "androiddeployqtstep.cpp", "androiddeployqtstep.h", "androiddebugsupport.cpp", @@ -46,8 +45,6 @@ Project { "androiddevicedialog.ui", "androiddevice.cpp", "androiddevice.h", - "androiddevicefactory.cpp", - "androiddevicefactory.h", "androiderrormessage.h", "androiderrormessage.cpp", "androidextralibrarylistmodel.cpp", @@ -75,12 +72,8 @@ Project { "androidqmltoolingsupport.h", "androidqtversion.cpp", "androidqtversion.h", - "androidqtversionfactory.cpp", - "androidqtversionfactory.h", "androidrunconfiguration.cpp", "androidrunconfiguration.h", - "androidrunenvironmentaspect.h", - "androidrunenvironmentaspect.cpp", "androidruncontrol.cpp", "androidruncontrol.h", "androidrunner.cpp", diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp index f6fcd85c68..17a9eb9b59 100644 --- a/src/plugins/android/androidavdmanager.cpp +++ b/src/plugins/android/androidavdmanager.cpp @@ -290,9 +290,9 @@ bool AndroidAvdManager::startAvdAsync(const QString &avdName) const return false; } auto avdProcess = new QProcess(); - avdProcess->setReadChannelMode(QProcess::MergedChannels); + avdProcess->setProcessChannelMode(QProcess::MergedChannels); QObject::connect(avdProcess, - static_cast<void (QProcess::*)(int)>(&QProcess::finished), + QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), avdProcess, std::bind(&avdProcessFinished, std::placeholders::_1, avdProcess)); @@ -429,12 +429,11 @@ bool AvdManagerOutputParser::parseAvd(const QStringList &deviceInfo, AndroidDevi } else if (valueForKey(avdInfoNameKey, line, &value)) { avd->avdname = value; } else if (valueForKey(avdInfoPathKey, line, &value)) { - const Utils::FileName avdPath = Utils::FileName::fromString(value); + const Utils::FilePath avdPath = Utils::FilePath::fromString(value); if (avdPath.exists()) { // Get ABI. - Utils::FileName configFile = avdPath; - configFile.appendPath("config.ini"); + const Utils::FilePath configFile = avdPath.pathAppended("config.ini"); QSettings config(configFile.toString(), QSettings::IniFormat); value = config.value(avdInfoAbiKey).toString(); if (!value.isEmpty()) @@ -443,9 +442,9 @@ bool AvdManagerOutputParser::parseAvd(const QStringList &deviceInfo, AndroidDevi qCDebug(avdManagerLog) << "Avd Parsing: Cannot find ABI:" << configFile; // Get Target - Utils::FileName avdInfoFile = avdPath.parentDir(); QString avdInfoFileName = avdPath.toFileInfo().baseName() + ".ini"; - avdInfoFile.appendPath(avdInfoFileName); + const Utils::FilePath + avdInfoFile = avdPath.parentDir().pathAppended(avdInfoFileName); QSettings avdInfo(avdInfoFile.toString(), QSettings::IniFormat); value = avdInfo.value(avdInfoTargetKey).toString(); if (!value.isEmpty()) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index d4320b039a..b9d77469b7 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -54,10 +54,11 @@ #include <utils/synchronousprocess.h> #include <utils/utilsicons.h> -#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h> - +#include <QDateTime> #include <QDialogButtonBox> #include <QHBoxLayout> +#include <QJsonDocument> +#include <QJsonObject> #include <QLabel> #include <QLineEdit> #include <QLoggingCategory> @@ -69,6 +70,7 @@ #include <memory> using namespace ProjectExplorer; +using namespace Utils; using namespace Android::Internal; namespace { @@ -89,10 +91,10 @@ static void setupProcessParameters(ProcessParameters *pp, const QString &command) { pp->setMacroExpander(bc->macroExpander()); - pp->setWorkingDirectory(bc->buildDirectory().toString()); + pp->setWorkingDirectory(bc->buildDirectory()); Utils::Environment env = bc->environment(); pp->setEnvironment(env); - pp->setCommand(command); + pp->setCommand(FilePath::fromString(command)); pp->setArguments(Utils::QtcProcess::joinArgs(arguments)); pp->resolveAll(); } @@ -160,13 +162,13 @@ bool AndroidBuildApkStep::init() OutputFormat::ErrorMessage); } - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target()->kit()); if (!version) return false; const QVersionNumber sdkToolsVersion = AndroidConfigurations::currentConfig().sdkToolsVersion(); if (sdkToolsVersion >= gradleScriptRevokedSdkVersion) { - if (!version->sourcePath().appendPath("src/3rdparty/gradle").exists()) { + if (!version->sourcePath().pathAppended("src/3rdparty/gradle").exists()) { emit addOutput(tr("The installed SDK tools version (%1) does not include Gradle " "scripts. The minimum Qt version required for Gradle build to work " "is %2").arg(sdkToolsVersion.toString()).arg("5.9.0/5.6.3"), @@ -189,14 +191,19 @@ bool AndroidBuildApkStep::init() auto parser = new JavaParser; parser->setProjectFileList(Utils::transform(target()->project()->files(ProjectExplorer::Project::AllFiles), - &Utils::FileName::toString)); + &Utils::FilePath::toString)); RunConfiguration *rc = target()->activeRunConfiguration(); - const ProjectNode *node = rc ? target()->project()->findNodeForBuildKey(rc->buildKey()) : nullptr; + const QString buildKey = rc ? rc->buildKey() : QString(); + const ProjectNode *node = rc ? target()->project()->findNodeForBuildKey(buildKey) : nullptr; + + QString sourceDirName; + if (node) + sourceDirName = node->data(Constants::AndroidPackageSourceDir).toString(); - QFileInfo sourceDirInfo(node ? node->data(Constants::AndroidPackageSourceDir).toString() : QString()); - parser->setSourceDirectory(Utils::FileName::fromString(sourceDirInfo.canonicalFilePath())); - parser->setBuildDirectory(Utils::FileName::fromString(bc->buildDirectory().appendPath(Constants::ANDROID_BUILDDIRECTORY).toString())); + QFileInfo sourceDirInfo(sourceDirName); + parser->setSourceDirectory(Utils::FilePath::fromString(sourceDirInfo.canonicalFilePath())); + parser->setBuildDirectory(bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY)); setOutputParser(parser); m_openPackageLocationForRun = m_openPackageLocation; @@ -213,7 +220,7 @@ bool AndroidBuildApkStep::init() if (Utils::HostOsInfo::isWindowsHost()) command += ".exe"; - QString outputDir = bc->buildDirectory().appendPath(Constants::ANDROID_BUILDDIRECTORY).toString(); + QString outputDir = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString(); QString inputFile; if (node) @@ -273,7 +280,7 @@ bool AndroidBuildApkStep::init() // Generate arguments with keystore password concealed ProjectExplorer::ProcessParameters pp2; setupProcessParameters(&pp2, bc, argumentsPasswordConcealed, command); - m_command = pp2.effectiveCommand(); + m_command = pp2.effectiveCommand().toString(); m_argumentsPasswordConcealed = pp2.prettyArguments(); return true; @@ -340,13 +347,89 @@ bool AndroidBuildApkStep::verifyCertificatePassword() return success; } + +static bool copyFileIfNewer(const QString &sourceFileName, + const QString &destinationFileName) +{ + if (QFile::exists(destinationFileName)) { + QFileInfo destinationFileInfo(destinationFileName); + QFileInfo sourceFileInfo(sourceFileName); + if (sourceFileInfo.lastModified() <= destinationFileInfo.lastModified()) + return true; + if (!QFile(destinationFileName).remove()) + return false; + } + + if (!QDir().mkpath(QFileInfo(destinationFileName).path())) + return false; + return QFile::copy(sourceFileName, destinationFileName); +} + void AndroidBuildApkStep::doRun() { if (m_skipBuilding) { - emit addOutput(tr("No application .pro file found, not building an APK."), BuildStep::OutputFormat::ErrorMessage); + emit addOutput(tr("Android deploy settings file not found, not building an APK."), BuildStep::OutputFormat::ErrorMessage); emit finished(true); return; } + + auto setup = [this] { + auto bc = target()->activeBuildConfiguration(); + Utils::FilePath androidLibsDir = bc->buildDirectory() + .pathAppended("android-build/libs") + .pathAppended(AndroidManager::targetArch(target())); + if (!androidLibsDir.exists() && !QDir{bc->buildDirectory().toString()}.mkpath(androidLibsDir.toString())) + return false; + + + QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target()); + RunConfiguration *rc = target()->activeRunConfiguration(); + const QString buildKey = rc ? rc->buildKey() : QString(); + const ProjectNode *node = rc ? target()->project()->findNodeForBuildKey(buildKey) : nullptr; + + if (!node) + return false; + + auto targets = node->data(Android::Constants::AndroidTargets).toStringList(); + if (targets.isEmpty()) + return true; // qmake does this job for us + + // Copy targets to android build folder + for (const auto &target : targets) { + if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) + return false; + } + + QString extraLibs = node->data(Android::Constants::AndroidExtraLibs).toString(); + if (!extraLibs.isEmpty()) + deploySettings["android-extra-libs"] = extraLibs; + + QString androidSrcs = node->data(Android::Constants::AndroidPackageSourceDir).toString(); + if (!androidSrcs.isEmpty()) + deploySettings["android-package-source-directory"] = androidSrcs; + + QString qmlImportPath = node->data("QML_IMPORT_PATH").toString(); + if (!qmlImportPath.isEmpty()) + deploySettings["qml-import-paths"] = qmlImportPath; + + QString qmlRootPath = node->data("QML_ROOT_PATH").toString(); + if (qmlRootPath.isEmpty()) + qmlRootPath = target()->project()->rootProjectDirectory().toString(); + deploySettings["qml-root-path"] = qmlRootPath; + + QFile f{bc->buildDirectory().pathAppended("android_deployment_settings.json").toString()}; + if (!f.open(QIODevice::WriteOnly)) + return false; + f.write(QJsonDocument{deploySettings}.toJson()); + return true; + }; + + if (!setup()) { + emit addOutput(tr("Cannot set up Android, not building an APK."), BuildStep::OutputFormat::ErrorMessage); + emit finished(false); + return; + } + AbstractProcessStep::doRun(); } @@ -360,7 +443,7 @@ void AndroidBuildApkStep::processStarted() bool AndroidBuildApkStep::fromMap(const QVariantMap &map) { - m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString()); + m_keystorePath = Utils::FilePath::fromString(map.value(KeystoreLocationKey).toString()); m_signPackage = false; // don't restore this m_buildTargetSdk = map.value(BuildTargetSdkKey).toString(); if (m_buildTargetSdk.isEmpty()) { @@ -382,7 +465,7 @@ QVariantMap AndroidBuildApkStep::toMap() const return map; } -Utils::FileName AndroidBuildApkStep::keystorePath() +Utils::FilePath AndroidBuildApkStep::keystorePath() { return m_keystorePath; } @@ -398,7 +481,19 @@ void AndroidBuildApkStep::setBuildTargetSdk(const QString &sdk) AndroidManager::updateGradleProperties(target()); } -void AndroidBuildApkStep::setKeystorePath(const Utils::FileName &path) +QVariant AndroidBuildApkStep::data(Core::Id id) const +{ + if (id == Constants::AndroidNdkPlatform) + return AndroidConfigurations::currentConfig().bestNdkPlatformMatch(AndroidManager::minimumSDK(target())).mid(8); + if (id == Constants::NdkLocation) + return QVariant::fromValue(AndroidConfigurations::currentConfig().ndkLocation()); + if (id == Constants::AndroidABI) + return AndroidManager::targetArch(target()); + + return AbstractProcessStep::data(id); +} + +void AndroidBuildApkStep::setKeystorePath(const Utils::FilePath &path) { m_keystorePath = path; m_certificatePasswd.clear(); @@ -568,7 +663,6 @@ namespace Internal { AndroidBuildApkStepFactory::AndroidBuildApkStepFactory() { registerStep<AndroidBuildApkStep>(Constants::ANDROID_BUILD_APK_ID); - setSupportedProjectType(QmakeProjectManager::Constants::QMAKEPROJECT_ID); setSupportedDeviceType(Constants::ANDROID_DEVICE_TYPE); setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); setDisplayName(AndroidBuildApkStep::tr("Build Android APK")); diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h index e336d5c5c7..9e7ec4a07a 100644 --- a/src/plugins/android/androidbuildapkstep.h +++ b/src/plugins/android/androidbuildapkstep.h @@ -51,8 +51,8 @@ public: QVariantMap toMap() const override; // signing - Utils::FileName keystorePath(); - void setKeystorePath(const Utils::FileName &path); + Utils::FilePath keystorePath(); + void setKeystorePath(const Utils::FilePath &path); void setKeystorePassword(const QString &pwd); void setCertificateAlias(const QString &alias); void setCertificatePassword(const QString &pwd); @@ -76,6 +76,7 @@ public: QString buildTargetSdk() const; void setBuildTargetSdk(const QString &sdk); + QVariant data(Core::Id id) const override; private: Q_INVOKABLE void showInGraphicalShell(); @@ -96,7 +97,7 @@ private: bool m_addDebugger = true; QString m_buildTargetSdk; - Utils::FileName m_keystorePath; + Utils::FilePath m_keystorePath; QString m_keystorePasswd; QString m_certificateAlias; QString m_certificatePasswd; diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp index 02d0c3e92b..ff8441f889 100644 --- a/src/plugins/android/androidbuildapkwidget.cpp +++ b/src/plugins/android/androidbuildapkwidget.cpp @@ -24,14 +24,15 @@ ** ****************************************************************************/ -#include "androidbuildapkstep.h" #include "androidbuildapkwidget.h" + +#include "androidbuildapkstep.h" #include "androidconfigurations.h" +#include "androidextralibrarylistmodel.h" #include "androidcreatekeystorecertificate.h" #include "androidmanager.h" #include "androidsdkmanager.h" #include "createandroidmanifestwizard.h" -#include "ui_androidbuildapkwidget.h" #include <projectexplorer/buildconfiguration.h> #include <projectexplorer/project.h> @@ -45,8 +46,10 @@ #include <utils/pathchooser.h> #include <utils/utilsicons.h> -#include <QFileDialog> +#include <QCheckBox> +#include <QComboBox> #include <QGroupBox> +#include <QFileDialog> #include <QLabel> #include <QListView> #include <QPushButton> @@ -56,271 +59,297 @@ #include <algorithm> using namespace ProjectExplorer; +using namespace Utils; namespace Android { namespace Internal { -AndroidBuildApkInnerWidget::AndroidBuildApkInnerWidget(AndroidBuildApkStep *step) - : ProjectExplorer::BuildStepConfigWidget(step), - m_ui(new Ui::AndroidBuildApkWidget), - m_step(step) +AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step) + : BuildStepConfigWidget(step), m_step(step) { - m_ui->setupUi(this); setDisplayName("<b>" + tr("Build Android APK") + "</b>"); setSummaryText(displayName()); - // Target sdk combobox - const int minApiSupported = AndroidManager::apiLevelRange().first; - QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::sdkManager()-> - filteredSdkPlatforms(minApiSupported)); - targets.removeDuplicates(); - m_ui->targetSDKComboBox->addItems(targets); - m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::buildTargetSDK(step->target()))); - - // Ministro - if (m_step->useMinistro()) - m_ui->ministroOption->setChecked(true); - - // signing - m_ui->signPackageCheckBox->setChecked(m_step->signPackage()); - m_ui->KeystoreLocationPathChooser->setExpectedKind(Utils::PathChooser::File); - m_ui->KeystoreLocationPathChooser->lineEdit()->setReadOnly(true); - m_ui->KeystoreLocationPathChooser->setPath(m_step->keystorePath().toUserOutput()); - m_ui->KeystoreLocationPathChooser->setInitialBrowsePathBackup(QDir::homePath()); - m_ui->KeystoreLocationPathChooser->setPromptDialogFilter(tr("Keystore files (*.keystore *.jks)")); - m_ui->KeystoreLocationPathChooser->setPromptDialogTitle(tr("Select Keystore File")); - m_ui->signingDebugWarningIcon->setPixmap(Utils::Icons::WARNING.pixmap()); - m_ui->signingDebugWarningIcon->hide(); - m_ui->signingDebugWarningLabel->hide(); - signPackageCheckBoxToggled(m_step->signPackage()); - - m_ui->verboseOutputCheckBox->setChecked(m_step->verboseOutput()); - m_ui->openPackageLocationCheckBox->setChecked(m_step->openPackageLocation()); - m_ui->addDebuggerCheckBox->setChecked(m_step->addDebugger()); + auto vbox = new QVBoxLayout(this); + vbox->addWidget(createSignPackageGroup()); + vbox->addWidget(createApplicationGroup()); + vbox->addWidget(createAdvancedGroup()); + vbox->addWidget(createCreateTemplatesGroup()); + vbox->addWidget(createAdditionalLibrariesGroup()); - // target sdk - connect(m_ui->targetSDKComboBox, - static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated), - this, &AndroidBuildApkInnerWidget::setTargetSdk); + connect(m_step->buildConfiguration(), &BuildConfiguration::buildTypeChanged, + this, &AndroidBuildApkWidget::updateSigningWarning); - // deployment options - connect(m_ui->ministroOption, &QAbstractButton::clicked, - m_step, &AndroidBuildApkStep::setUseMinistro); - - connect(m_ui->openPackageLocationCheckBox, &QAbstractButton::toggled, - this, &AndroidBuildApkInnerWidget::openPackageLocationCheckBoxToggled); - connect(m_ui->verboseOutputCheckBox, &QAbstractButton::toggled, - this, &AndroidBuildApkInnerWidget::verboseOutputCheckBoxToggled); - connect(m_ui->addDebuggerCheckBox, &QAbstractButton::toggled, - m_step, &AndroidBuildApkStep::setAddDebugger); - - //signing - connect(m_ui->signPackageCheckBox, &QAbstractButton::toggled, - this, &AndroidBuildApkInnerWidget::signPackageCheckBoxToggled); - connect(m_ui->KeystoreCreatePushButton, &QAbstractButton::clicked, - this, &AndroidBuildApkInnerWidget::createKeyStore); - connect(m_ui->KeystoreLocationPathChooser, &Utils::PathChooser::pathChanged, - this, &AndroidBuildApkInnerWidget::updateKeyStorePath); - connect(m_ui->certificatesAliasComboBox, - static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated), - this, &AndroidBuildApkInnerWidget::certificatesAliasComboBoxActivated); - connect(m_ui->certificatesAliasComboBox, - static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged), - this, &AndroidBuildApkInnerWidget::certificatesAliasComboBoxCurrentIndexChanged); - - connect(m_step->buildConfiguration(), &ProjectExplorer::BuildConfiguration::buildTypeChanged, - this, &AndroidBuildApkInnerWidget::updateSigningWarning); + connect(m_signPackageCheckBox, &QAbstractButton::clicked, + m_addDebuggerCheckBox, &QWidget::setEnabled); + signPackageCheckBoxToggled(m_step->signPackage()); updateSigningWarning(); } -AndroidBuildApkInnerWidget::~AndroidBuildApkInnerWidget() +QWidget *AndroidBuildApkWidget::createApplicationGroup() { - delete m_ui; -} - -void AndroidBuildApkInnerWidget::setTargetSdk(const QString &sdk) -{ - m_step->setBuildTargetSdk(sdk); -} + const int minApiSupported = AndroidManager::apiLevelRange().first; + QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::sdkManager()-> + filteredSdkPlatforms(minApiSupported)); + targets.removeDuplicates(); -void AndroidBuildApkInnerWidget::signPackageCheckBoxToggled(bool checked) -{ - m_ui->certificatesAliasComboBox->setEnabled(checked); - m_step->setSignPackage(checked); - m_ui->addDebuggerCheckBox->setChecked(!checked); - updateSigningWarning(); - if (!checked) - return; - if (!m_step->keystorePath().isEmpty()) - setCertificates(); -} + auto group = new QGroupBox(tr("Application"), this); -void AndroidBuildApkInnerWidget::createKeyStore() -{ - AndroidCreateKeystoreCertificate d; - if (d.exec() != QDialog::Accepted) - return; - m_ui->KeystoreLocationPathChooser->setPath(d.keystoreFilePath().toUserOutput()); - m_step->setKeystorePath(d.keystoreFilePath()); - m_step->setKeystorePassword(d.keystorePassword()); - m_step->setCertificateAlias(d.certificateAlias()); - m_step->setCertificatePassword(d.certificatePassword()); - setCertificates(); -} + auto targetSDKComboBox = new QComboBox(group); + targetSDKComboBox->addItems(targets); + targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::buildTargetSDK(step()->target()))); -void AndroidBuildApkInnerWidget::setCertificates() -{ - QAbstractItemModel *certificates = m_step->keystoreCertificates(); - if (certificates) { - m_ui->signPackageCheckBox->setChecked(certificates); - m_ui->certificatesAliasComboBox->setModel(certificates); - } -} + const auto cbActivated = QOverload<int>::of(&QComboBox::activated); + connect(targetSDKComboBox, cbActivated, this, [this, targetSDKComboBox](int idx) { + const QString sdk = targetSDKComboBox->itemText(idx); + m_step->setBuildTargetSdk(sdk); + }); -void AndroidBuildApkInnerWidget::updateKeyStorePath(const QString &path) -{ - Utils::FileName file = Utils::FileName::fromString(path); - m_step->setKeystorePath(file); - m_ui->signPackageCheckBox->setChecked(!file.isEmpty()); - if (!file.isEmpty()) - setCertificates(); -} + auto hbox = new QHBoxLayout(group); + hbox->addWidget(new QLabel(tr("Android build SDK:"), group)); + hbox->addWidget(targetSDKComboBox); -void AndroidBuildApkInnerWidget::certificatesAliasComboBoxActivated(const QString &alias) -{ - if (alias.length()) - m_step->setCertificateAlias(alias); + return group; } -void AndroidBuildApkInnerWidget::certificatesAliasComboBoxCurrentIndexChanged(const QString &alias) +QWidget *AndroidBuildApkWidget::createSignPackageGroup() { - if (alias.length()) - m_step->setCertificateAlias(alias); -} + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + + auto group = new QGroupBox(tr("Sign package"), this); + + auto keystoreLocationLabel = new QLabel(tr("Keystore:"), group); + keystoreLocationLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + + auto keystoreLocationChooser = new PathChooser(group); + keystoreLocationChooser->setExpectedKind(PathChooser::File); + keystoreLocationChooser->lineEdit()->setReadOnly(true); + keystoreLocationChooser->setPath(m_step->keystorePath().toUserOutput()); + keystoreLocationChooser->setInitialBrowsePathBackup(QDir::homePath()); + keystoreLocationChooser->setPromptDialogFilter(tr("Keystore files (*.keystore *.jks)")); + keystoreLocationChooser->setPromptDialogTitle(tr("Select Keystore File")); + connect(keystoreLocationChooser, &PathChooser::pathChanged, this, [this](const QString &path) { + FilePath file = FilePath::fromString(path); + m_step->setKeystorePath(file); + m_signPackageCheckBox->setChecked(!file.isEmpty()); + if (!file.isEmpty()) + setCertificates(); + }); -void AndroidBuildApkInnerWidget::openPackageLocationCheckBoxToggled(bool checked) -{ - m_step->setOpenPackageLocation(checked); -} + auto keystoreCreateButton = new QPushButton(tr("Create..."), group); + connect(keystoreCreateButton, &QAbstractButton::clicked, this, [this, keystoreLocationChooser] { + AndroidCreateKeystoreCertificate d; + if (d.exec() != QDialog::Accepted) + return; + keystoreLocationChooser->setPath(d.keystoreFilePath().toUserOutput()); + m_step->setKeystorePath(d.keystoreFilePath()); + m_step->setKeystorePassword(d.keystorePassword()); + m_step->setCertificateAlias(d.certificateAlias()); + m_step->setCertificatePassword(d.certificatePassword()); + setCertificates(); + }); -void AndroidBuildApkInnerWidget::verboseOutputCheckBoxToggled(bool checked) -{ - m_step->setVerboseOutput(checked); + m_signPackageCheckBox = new QCheckBox(tr("Sign package"), group); + m_signPackageCheckBox->setChecked(m_step->signPackage()); + + m_signingDebugWarningIcon = new QLabel(group); + m_signingDebugWarningIcon->setSizePolicy(sizePolicy); + m_signingDebugWarningIcon->setPixmap(Icons::WARNING.pixmap()); + m_signingDebugWarningIcon->hide(); + + m_signingDebugWarningLabel = new QLabel(tr("Signing a debug package"), group); + m_signingDebugWarningLabel->setSizePolicy(sizePolicy); + m_signingDebugWarningLabel->hide(); + + auto certificateAliasLabel = new QLabel(tr("Certificate alias:"), group); + certificateAliasLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + + m_certificatesAliasComboBox = new QComboBox(group); + m_certificatesAliasComboBox->setEnabled(false); + QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + m_certificatesAliasComboBox->setSizePolicy(sizePolicy2); + m_certificatesAliasComboBox->setMinimumSize(QSize(300, 0)); + + auto horizontalLayout_2 = new QHBoxLayout; + horizontalLayout_2->addWidget(keystoreLocationLabel); + horizontalLayout_2->addWidget(keystoreLocationChooser); + horizontalLayout_2->addWidget(keystoreCreateButton); + + auto horizontalLayout_3 = new QHBoxLayout; + horizontalLayout_3->addWidget(m_signingDebugWarningIcon); + horizontalLayout_3->addWidget(m_signingDebugWarningLabel); + horizontalLayout_3->addWidget(certificateAliasLabel); + horizontalLayout_3->addWidget(m_certificatesAliasComboBox); + + auto vbox = new QVBoxLayout(group); + vbox->addLayout(horizontalLayout_2); + vbox->addWidget(m_signPackageCheckBox); + vbox->addLayout(horizontalLayout_3); + + connect(m_signPackageCheckBox, &QAbstractButton::toggled, + this, &AndroidBuildApkWidget::signPackageCheckBoxToggled); + + auto updateAlias = [this](int idx) { + QString alias = m_certificatesAliasComboBox->itemText(idx); + if (alias.length()) + m_step->setCertificateAlias(alias); + }; + + const auto cbActivated = QOverload<int>::of(&QComboBox::activated); + const auto cbCurrentIndexChanged = QOverload<int>::of(&QComboBox::currentIndexChanged); + + connect(m_certificatesAliasComboBox, cbActivated, this, updateAlias); + connect(m_certificatesAliasComboBox, cbCurrentIndexChanged, this, updateAlias); + + return group; } -void AndroidBuildApkInnerWidget::updateSigningWarning() +QWidget *AndroidBuildApkWidget::createAdvancedGroup() { - bool nonRelease = m_step->buildConfiguration()->buildType() - != ProjectExplorer::BuildConfiguration::Release; - if (m_step->signPackage() && nonRelease) { - m_ui->signingDebugWarningIcon->setVisible(true); - m_ui->signingDebugWarningLabel->setVisible(true); - } else { - m_ui->signingDebugWarningIcon->setVisible(false); - m_ui->signingDebugWarningLabel->setVisible(false); - } -} + auto group = new QGroupBox(tr("Advanced Actions"), this); + + auto openPackageLocationCheckBox = new QCheckBox(tr("Open package location after build"), group); + openPackageLocationCheckBox->setChecked(m_step->openPackageLocation()); + connect(openPackageLocationCheckBox, &QAbstractButton::toggled, + this, [this](bool checked) { m_step->setOpenPackageLocation(checked); }); + + m_addDebuggerCheckBox = new QCheckBox(tr("Add debug server"), group); + m_addDebuggerCheckBox->setEnabled(false); + m_addDebuggerCheckBox->setToolTip(tr("Packages debug server with " + "the APK to enable debugging. For the signed APK this option is unchecked by default.")); + m_addDebuggerCheckBox->setChecked(m_step->addDebugger()); + connect(m_addDebuggerCheckBox, &QAbstractButton::toggled, + m_step, &AndroidBuildApkStep::setAddDebugger); + auto verboseOutputCheckBox = new QCheckBox(tr("Verbose output"), group); + verboseOutputCheckBox->setChecked(m_step->verboseOutput()); -// AndroidBuildApkWidget + auto ministroOption = new QCheckBox(tr("Use Ministro service to install Qt"), group); + ministroOption->setToolTip(tr("Uses the external Ministro application to download and maintain Qt libraries.")); + ministroOption->setChecked(m_step->useMinistro()); + connect(ministroOption, &QAbstractButton::clicked, + m_step, &AndroidBuildApkStep::setUseMinistro); -AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step) : - BuildStepConfigWidget(step), - m_step(step) -{ - setDisplayName("<b>" + tr("Build Android APK") + "</b>"); - setSummaryText("<b>" + tr("Build Android APK") + "</b>"); + auto vbox = new QVBoxLayout(group); + vbox->addWidget(openPackageLocationCheckBox); + vbox->addWidget(verboseOutputCheckBox); + vbox->addWidget(m_addDebuggerCheckBox); + vbox->addWidget(ministroOption); - m_extraLibraryListModel = new AndroidExtraLibraryListModel(m_step->target(), this); + connect(verboseOutputCheckBox, &QAbstractButton::toggled, + this, [this](bool checked) { m_step->setVerboseOutput(checked); }); - auto base = new AndroidBuildApkInnerWidget(step); - base->layout()->setContentsMargins(0, 0, 0, 0); + return group; +} +QWidget *AndroidBuildApkWidget::createCreateTemplatesGroup() +{ auto createTemplatesGroupBox = new QGroupBox(tr("Android")); createTemplatesGroupBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); auto createAndroidTemplatesButton = new QPushButton(tr("Create Templates")); + connect(createAndroidTemplatesButton, &QAbstractButton::clicked, this, [this] { + CreateAndroidManifestWizard wizard(m_step->target()); + wizard.exec(); + }); auto horizontalLayout = new QHBoxLayout(createTemplatesGroupBox); horizontalLayout->addWidget(createAndroidTemplatesButton); horizontalLayout->addStretch(1); - auto additionalLibrariesGroupBox = new QGroupBox(tr("Additional Libraries")); - additionalLibrariesGroupBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - - m_androidExtraLibsListView = new QListView; - m_androidExtraLibsListView->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_androidExtraLibsListView->setToolTip(tr("List of extra libraries to include in Android package and load on startup.")); - m_androidExtraLibsListView->setModel(m_extraLibraryListModel); - - auto addAndroidExtraLibButton = new QToolButton; - addAndroidExtraLibButton->setText(tr("Add...")); - addAndroidExtraLibButton->setToolTip(tr("Select library to include in package.")); - addAndroidExtraLibButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - addAndroidExtraLibButton->setToolButtonStyle(Qt::ToolButtonTextOnly); - - m_removeAndroidExtraLibButton = new QToolButton; - m_removeAndroidExtraLibButton->setText(tr("Remove")); - m_removeAndroidExtraLibButton->setToolTip(tr("Remove currently selected library from list.")); - - auto androidExtraLibsButtonLayout = new QVBoxLayout(); - androidExtraLibsButtonLayout->addWidget(addAndroidExtraLibButton); - androidExtraLibsButtonLayout->addWidget(m_removeAndroidExtraLibButton); - androidExtraLibsButtonLayout->addStretch(1); - - auto androidExtraLibsLayout = new QHBoxLayout(additionalLibrariesGroupBox); - androidExtraLibsLayout->addWidget(m_androidExtraLibsListView); - androidExtraLibsLayout->addLayout(androidExtraLibsButtonLayout); - - auto topLayout = new QVBoxLayout(this); - topLayout->addWidget(base); - topLayout->addWidget(createTemplatesGroupBox); - topLayout->addWidget(additionalLibrariesGroupBox); + return createTemplatesGroupBox; +} - connect(createAndroidTemplatesButton, &QAbstractButton::clicked, this, [this] { - CreateAndroidManifestWizard wizard(m_step->target()); - wizard.exec(); +QWidget *AndroidBuildApkWidget::createAdditionalLibrariesGroup() +{ + auto group = new QGroupBox(tr("Additional Libraries")); + group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + + auto libsModel = new AndroidExtraLibraryListModel(m_step->target(), this); + connect(libsModel, &AndroidExtraLibraryListModel::enabledChanged, + group, &QWidget::setEnabled); + + auto libsView = new QListView; + libsView->setSelectionMode(QAbstractItemView::ExtendedSelection); + libsView->setToolTip(tr("List of extra libraries to include in Android package and load on startup.")); + libsView->setModel(libsModel); + + auto addLibButton = new QToolButton; + addLibButton->setText(tr("Add...")); + addLibButton->setToolTip(tr("Select library to include in package.")); + addLibButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + addLibButton->setToolButtonStyle(Qt::ToolButtonTextOnly); + connect(addLibButton, &QAbstractButton::clicked, this, [this, libsModel] { + QStringList fileNames = QFileDialog::getOpenFileNames(this, + tr("Select additional libraries"), + QDir::homePath(), + tr("Libraries (*.so)")); + if (!fileNames.isEmpty()) + libsModel->addEntries(fileNames); }); - connect(addAndroidExtraLibButton, &QAbstractButton::clicked, - this, &AndroidBuildApkWidget::addAndroidExtraLib); + auto removeLibButton = new QToolButton; + removeLibButton->setText(tr("Remove")); + removeLibButton->setToolTip(tr("Remove currently selected library from list.")); + connect(removeLibButton, &QAbstractButton::clicked, this, [libsModel, libsView] { + QModelIndexList removeList = libsView->selectionModel()->selectedIndexes(); + libsModel->removeEntries(removeList); + }); - connect(m_removeAndroidExtraLibButton, &QAbstractButton::clicked, - this, &AndroidBuildApkWidget::removeAndroidExtraLib); + auto libsButtonLayout = new QVBoxLayout; + libsButtonLayout->addWidget(addLibButton); + libsButtonLayout->addWidget(removeLibButton); + libsButtonLayout->addStretch(1); - connect(m_androidExtraLibsListView->selectionModel(), &QItemSelectionModel::selectionChanged, - this, &AndroidBuildApkWidget::checkEnableRemoveButton); + auto hbox = new QHBoxLayout(group); + hbox->addWidget(libsView); + hbox->addLayout(libsButtonLayout); - connect(m_extraLibraryListModel, &AndroidExtraLibraryListModel::enabledChanged, - additionalLibrariesGroupBox, &QWidget::setEnabled); + QItemSelectionModel *libSelection = libsView->selectionModel(); + connect(libSelection, &QItemSelectionModel::selectionChanged, this, [libSelection, removeLibButton] { + removeLibButton->setEnabled(libSelection->hasSelection()); + }); Target *target = m_step->target(); RunConfiguration *rc = target->activeRunConfiguration(); const ProjectNode *node = rc ? target->project()->findNodeForBuildKey(rc->buildKey()) : nullptr; - additionalLibrariesGroupBox->setEnabled(node && !node->parseInProgress()); + group->setEnabled(node && !node->parseInProgress()); + + return group; } -void AndroidBuildApkWidget::addAndroidExtraLib() +void AndroidBuildApkWidget::signPackageCheckBoxToggled(bool checked) { - QStringList fileNames = QFileDialog::getOpenFileNames(this, - tr("Select additional libraries"), - QDir::homePath(), - tr("Libraries (*.so)")); - - if (!fileNames.isEmpty()) - m_extraLibraryListModel->addEntries(fileNames); + m_certificatesAliasComboBox->setEnabled(checked); + m_step->setSignPackage(checked); + m_addDebuggerCheckBox->setChecked(!checked); + updateSigningWarning(); + if (!checked) + return; + if (!m_step->keystorePath().isEmpty()) + setCertificates(); } -void AndroidBuildApkWidget::removeAndroidExtraLib() +void AndroidBuildApkWidget::setCertificates() { - QModelIndexList removeList = m_androidExtraLibsListView->selectionModel()->selectedIndexes(); - m_extraLibraryListModel->removeEntries(removeList); + QAbstractItemModel *certificates = m_step->keystoreCertificates(); + if (certificates) { + m_signPackageCheckBox->setChecked(certificates); + m_certificatesAliasComboBox->setModel(certificates); + } } -void AndroidBuildApkWidget::checkEnableRemoveButton() +void AndroidBuildApkWidget::updateSigningWarning() { - m_removeAndroidExtraLibButton->setEnabled(m_androidExtraLibsListView->selectionModel()->hasSelection()); + bool nonRelease = m_step->buildConfiguration()->buildType() != BuildConfiguration::Release; + bool visible = m_step->signPackage() && nonRelease; + m_signingDebugWarningIcon->setVisible(visible); + m_signingDebugWarningLabel->setVisible(visible); } } // Internal diff --git a/src/plugins/android/androidbuildapkwidget.h b/src/plugins/android/androidbuildapkwidget.h index 03dcf21ec2..4c35b5dcd7 100644 --- a/src/plugins/android/androidbuildapkwidget.h +++ b/src/plugins/android/androidbuildapkwidget.h @@ -29,67 +29,43 @@ #include "android_global.h" #include "androidbuildapkstep.h" -#include "androidextralibrarylistmodel.h" #include <projectexplorer/buildstep.h> -#include <QListView> -#include <QToolButton> - QT_BEGIN_NAMESPACE -namespace Ui { class AndroidBuildApkWidget; } +class QCheckBox; +class QComboBox; +class QLabel; QT_END_NAMESPACE namespace Android { namespace Internal { -class AndroidBuildApkInnerWidget : public ProjectExplorer::BuildStepConfigWidget +class AndroidBuildApkWidget : public ProjectExplorer::BuildStepConfigWidget { Q_OBJECT public: - AndroidBuildApkInnerWidget(AndroidBuildApkStep *step); - ~AndroidBuildApkInnerWidget() override; + explicit AndroidBuildApkWidget(AndroidBuildApkStep *step); private: - void setTargetSdk(const QString &sdk); - void createKeyStore(); - void certificatesAliasComboBoxCurrentIndexChanged(const QString &alias); - void certificatesAliasComboBoxActivated(const QString &alias); + void setCertificates(); void updateSigningWarning(); - void openPackageLocationCheckBoxToggled(bool checked); - void verboseOutputCheckBoxToggled(bool checked); - void updateKeyStorePath(const QString &path); void signPackageCheckBoxToggled(bool checked); - void setCertificates(); - - Ui::AndroidBuildApkWidget *m_ui; - AndroidBuildApkStep *m_step; -}; - -class AndroidBuildApkWidget : public ProjectExplorer::BuildStepConfigWidget -{ - Q_OBJECT - -public: - explicit AndroidBuildApkWidget(AndroidBuildApkStep *step); - -signals: - void requestAndroidTemplates(); - -private: - void addAndroidExtraLib(); - void removeAndroidExtraLib(); - void checkEnableRemoveButton(); + QWidget *createApplicationGroup(); + QWidget *createSignPackageGroup(); + QWidget *createAdvancedGroup(); + QWidget *createCreateTemplatesGroup(); + QWidget *createAdditionalLibrariesGroup(); private: - QListView *m_androidExtraLibsListView = nullptr; - QToolButton *m_removeAndroidExtraLibButton = nullptr; - AndroidBuildApkStep *m_step = nullptr; - Android::AndroidExtraLibraryListModel *m_extraLibraryListModel = nullptr; - bool m_ignoreChange = false; + QCheckBox *m_signPackageCheckBox = nullptr; + QLabel *m_signingDebugWarningIcon = nullptr; + QLabel *m_signingDebugWarningLabel = nullptr; + QComboBox *m_certificatesAliasComboBox = nullptr; + QCheckBox *m_addDebuggerCheckBox = nullptr; }; } // namespace Internal diff --git a/src/plugins/android/androidbuildapkwidget.ui b/src/plugins/android/androidbuildapkwidget.ui deleted file mode 100644 index 98c53b64b7..0000000000 --- a/src/plugins/android/androidbuildapkwidget.ui +++ /dev/null @@ -1,217 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>AndroidBuildApkWidget</class> - <widget class="QWidget" name="AndroidBuildApkWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>641</width> - <height>349</height> - </rect> - </property> - <property name="windowTitle"> - <string/> - </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="1" column="0" colspan="2"> - <widget class="QGroupBox" name="signPackage"> - <property name="title"> - <string>Sign package</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="KeystoreLocationLabel"> - <property name="text"> - <string>Keystore:</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item> - <widget class="Utils::PathChooser" name="KeystoreLocationPathChooser" native="true"/> - </item> - <item> - <widget class="QPushButton" name="KeystoreCreatePushButton"> - <property name="text"> - <string>Create...</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QCheckBox" name="signPackageCheckBox"> - <property name="text"> - <string>Sign package</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="signingDebugWarningIcon"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="signingDebugWarningLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Signing a debug package</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="KeystoreLocationLabel_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Certificate alias:</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="certificatesAliasComboBox"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>300</width> - <height>0</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item row="0" column="0" colspan="2"> - <widget class="QGroupBox" name="application"> - <property name="title"> - <string>Application</string> - </property> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0"> - <widget class="QLabel" name="targetSDKLabel"> - <property name="text"> - <string>Android build SDK:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QComboBox" name="targetSDKComboBox"/> - </item> - </layout> - </widget> - </item> - <item row="2" column="0" colspan="2"> - <widget class="QGroupBox" name="advancedActions"> - <property name="title"> - <string>Advanced Actions</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" colspan="2"> - <widget class="QCheckBox" name="openPackageLocationCheckBox"> - <property name="text"> - <string>Open package location after build</string> - </property> - </widget> - </item> - <item row="2" column="0" colspan="2"> - <widget class="QCheckBox" name="addDebuggerCheckBox"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="toolTip"> - <string>Packages debug server with the APK to enable debugging. For the signed APK this option is unchecked by default.</string> - </property> - <property name="text"> - <string>Add debug server</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="2"> - <widget class="QCheckBox" name="verboseOutputCheckBox"> - <property name="text"> - <string>Verbose output</string> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="QCheckBox" name="ministroOption"> - <property name="toolTip"> - <string>Uses the external Ministro application to download and maintain Qt libraries.</string> - </property> - <property name="text"> - <string>Use Ministro service to install Qt</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>Utils::PathChooser</class> - <extends>QWidget</extends> - <header location="global">utils/pathchooser.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections> - <connection> - <sender>signPackageCheckBox</sender> - <signal>clicked(bool)</signal> - <receiver>addDebuggerCheckBox</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>113</x> - <y>178</y> - </hint> - <hint type="destinationlabel"> - <x>510</x> - <y>452</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index d26ca3c191..292fe361da 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -98,22 +98,16 @@ namespace { const QLatin1String ArmToolchainPrefix("arm-linux-androideabi"); const QLatin1String X86ToolchainPrefix("x86"); - const QLatin1String MipsToolchainPrefix("mipsel-linux-android"); - const QLatin1String Mips64ToolchainPrefix("mips64el-linux-android"); const QLatin1String AArch64ToolchainPrefix("aarch64-linux-android"); const QLatin1String X86_64ToolchainPrefix("x86_64"); const QLatin1String ArmToolsPrefix("arm-linux-androideabi"); const QLatin1String X86ToolsPrefix("i686-linux-android"); - const QLatin1String MipsToolsPrefix("mipsel-linux-android"); - const QLatin1String Mips64ToolsPrefix("mips64el-linux-android"); const QLatin1String AArch64ToolsPrefix("aarch64-linux-android"); const QLatin1String X86_64ToolsPrefix("x86_64-linux-android"); const QLatin1String ArmToolsDisplayName("arm"); const QLatin1String X86ToolsDisplayName("i686"); - const QLatin1String MipsToolsDisplayName("mipsel"); - const QLatin1String Mips64ToolsDisplayName("mips64el"); const QLatin1String AArch64ToolsDisplayName("aarch64"); const QLatin1String X86_64ToolsDisplayName("x86_64"); @@ -168,17 +162,12 @@ Abi AndroidConfig::abiForToolChainPrefix(const QString &toolchainPrefix) arch = Abi::ArmArchitecture; } else if (toolchainPrefix == X86ToolchainPrefix) { arch = Abi::X86Architecture; - } else if (toolchainPrefix == MipsToolchainPrefix) { - arch = Abi::MipsArchitecture; } else if (toolchainPrefix == AArch64ToolchainPrefix) { arch = Abi::ArmArchitecture; wordWidth = 64; } else if (toolchainPrefix == X86_64ToolchainPrefix) { arch = Abi::X86Architecture; wordWidth = 64; - } else if (toolchainPrefix == Mips64ToolchainPrefix) { - arch = Abi::MipsArchitecture; - wordWidth = 64; } return Abi(arch, Abi::LinuxOS, Abi::AndroidLinuxFlavor, Abi::ElfFormat, wordWidth); @@ -195,10 +184,6 @@ QLatin1String AndroidConfig::toolchainPrefix(const Abi &abi) if (abi.wordWidth() == 64) return X86_64ToolchainPrefix; return X86ToolchainPrefix; - case Abi::MipsArchitecture: - if (abi.wordWidth() == 64) - return Mips64ToolchainPrefix; - return MipsToolchainPrefix; default: return Unknown; } @@ -215,10 +200,6 @@ QLatin1String AndroidConfig::toolsPrefix(const Abi &abi) if (abi.wordWidth() == 64) return X86_64ToolsPrefix; return X86ToolsPrefix; - case Abi::MipsArchitecture: - if (abi.wordWidth() == 64) - return Mips64ToolsPrefix; - return MipsToolsPrefix; default: return Unknown; } @@ -235,10 +216,6 @@ QLatin1String AndroidConfig::displayName(const Abi &abi) if (abi.wordWidth() == 64) return X86_64ToolsDisplayName; return X86ToolsDisplayName; - case Abi::MipsArchitecture: - if (abi.wordWidth() == 64) - return Mips64ToolsDisplayName; - return MipsToolsDisplayName; default: return Unknown; } @@ -248,23 +225,23 @@ void AndroidConfig::load(const QSettings &settings) { // user settings m_partitionSize = settings.value(PartitionSizeKey, 1024).toInt(); - m_sdkLocation = FileName::fromString(settings.value(SDKLocationKey).toString()); + m_sdkLocation = FilePath::fromString(settings.value(SDKLocationKey).toString()); m_sdkManagerToolArgs = settings.value(SDKManagerToolArgsKey).toStringList(); - m_ndkLocation = FileName::fromString(settings.value(NDKLocationKey).toString()); - m_openJDKLocation = FileName::fromString(settings.value(OpenJDKLocationKey).toString()); - m_keystoreLocation = FileName::fromString(settings.value(KeystoreLocationKey).toString()); + m_ndkLocation = FilePath::fromString(settings.value(NDKLocationKey).toString()); + m_openJDKLocation = FilePath::fromString(settings.value(OpenJDKLocationKey).toString()); + m_keystoreLocation = FilePath::fromString(settings.value(KeystoreLocationKey).toString()); m_toolchainHost = settings.value(ToolchainHostKey).toString(); m_automaticKitCreation = settings.value(AutomaticKitCreationKey, true).toBool(); PersistentSettingsReader reader; - if (reader.load(FileName::fromString(sdkSettingsFileName())) + if (reader.load(FilePath::fromString(sdkSettingsFileName())) && settings.value(changeTimeStamp).toInt() != QFileInfo(sdkSettingsFileName()).lastModified().toMSecsSinceEpoch() / 1000) { // persisten settings - m_sdkLocation = FileName::fromString(reader.restoreValue(SDKLocationKey, m_sdkLocation.toString()).toString()); + m_sdkLocation = FilePath::fromString(reader.restoreValue(SDKLocationKey, m_sdkLocation.toString()).toString()); m_sdkManagerToolArgs = reader.restoreValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs).toStringList(); - m_ndkLocation = FileName::fromString(reader.restoreValue(NDKLocationKey, m_ndkLocation.toString()).toString()); - m_openJDKLocation = FileName::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString()); - m_keystoreLocation = FileName::fromString(reader.restoreValue(KeystoreLocationKey, m_keystoreLocation.toString()).toString()); + m_ndkLocation = FilePath::fromString(reader.restoreValue(NDKLocationKey, m_ndkLocation.toString()).toString()); + m_openJDKLocation = FilePath::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString()); + m_keystoreLocation = FilePath::fromString(reader.restoreValue(KeystoreLocationKey, m_keystoreLocation.toString()).toString()); m_toolchainHost = reader.restoreValue(ToolchainHostKey, m_toolchainHost).toString(); m_automaticKitCreation = reader.restoreValue(AutomaticKitCreationKey, m_automaticKitCreation).toBool(); // persistent settings @@ -294,8 +271,7 @@ void AndroidConfig::updateNdkInformation() const if (m_NdkInformationUpToDate) return; m_availableNdkPlatforms.clear(); - FileName path = ndkLocation(); - QDirIterator it(path.appendPath("platforms").toString(), QStringList("android-*"), QDir::Dirs); + QDirIterator it(m_ndkLocation.pathAppended("platforms").toString(), QStringList("android-*"), QDir::Dirs); while (it.hasNext()) { const QString &fileName = it.next(); m_availableNdkPlatforms.push_back(fileName.midRef(fileName.lastIndexOf(QLatin1Char('-')) + 1).toInt()); @@ -317,8 +293,7 @@ void AndroidConfig::updateNdkInformation() const default: /* unknown host */ return; } - path = ndkLocation(); - QDirIterator jt(path.appendPath(QLatin1String("prebuilt")).toString(), hostPatterns, QDir::Dirs); + QDirIterator jt(m_ndkLocation.pathAppended("prebuilt").toString(), hostPatterns, QDir::Dirs); if (jt.hasNext()) { jt.next(); m_toolchainHost = jt.fileName(); @@ -338,76 +313,62 @@ QString AndroidConfig::apiLevelNameFor(const SdkPlatform *platform) QString("android-%1").arg(platform->apiLevel()) : ""; } -FileName AndroidConfig::adbToolPath() const +FilePath AndroidConfig::adbToolPath() const { - FileName path = m_sdkLocation; - return path.appendPath(QLatin1String("platform-tools/adb" QTC_HOST_EXE_SUFFIX)); + return m_sdkLocation.pathAppended("platform-tools/adb" QTC_HOST_EXE_SUFFIX); } -FileName AndroidConfig::androidToolPath() const +FilePath AndroidConfig::androidToolPath() const { if (HostOsInfo::isWindowsHost()) { // I want to switch from using android.bat to using an executable. All it really does is call // Java and I've made some progress on it. So if android.exe exists, return that instead. - FileName path = m_sdkLocation; - path.appendPath(QLatin1String("tools/android" QTC_HOST_EXE_SUFFIX)); + const FilePath path = m_sdkLocation.pathAppended("tools/android" QTC_HOST_EXE_SUFFIX); if (path.exists()) return path; - path = m_sdkLocation; - return path.appendPath(QLatin1String("tools/android" ANDROID_BAT_SUFFIX)); - } else { - FileName path = m_sdkLocation; - return path.appendPath(QLatin1String("tools/android")); + return m_sdkLocation.pathAppended("tools/android" ANDROID_BAT_SUFFIX); } + return m_sdkLocation.pathAppended("tools/android"); } -FileName AndroidConfig::emulatorToolPath() const +FilePath AndroidConfig::emulatorToolPath() const { - FileName path = m_sdkLocation; QString relativePath = "emulator/emulator"; if (sdkToolsVersion() < QVersionNumber(25, 3, 0)) relativePath = "tools/emulator"; - return path.appendPath(relativePath + QTC_HOST_EXE_SUFFIX); + return m_sdkLocation.pathAppended(relativePath + QTC_HOST_EXE_SUFFIX); } -FileName AndroidConfig::sdkManagerToolPath() const +FilePath AndroidConfig::sdkManagerToolPath() const { - FileName sdkPath = m_sdkLocation; QString toolPath = "tools/bin/sdkmanager"; if (HostOsInfo::isWindowsHost()) toolPath += ANDROID_BAT_SUFFIX; - sdkPath = sdkPath.appendPath(toolPath); - return sdkPath; + return m_sdkLocation.pathAppended(toolPath); } -FileName AndroidConfig::avdManagerToolPath() const +FilePath AndroidConfig::avdManagerToolPath() const { - FileName avdManagerPath = m_sdkLocation; QString toolPath = "tools/bin/avdmanager"; if (HostOsInfo::isWindowsHost()) toolPath += ANDROID_BAT_SUFFIX; - avdManagerPath = avdManagerPath.appendPath(toolPath); - return avdManagerPath; + return m_sdkLocation.pathAppended(toolPath); } -FileName AndroidConfig::aaptToolPath() const +FilePath AndroidConfig::aaptToolPath() const { - Utils::FileName aaptToolPath = m_sdkLocation; - aaptToolPath.appendPath("build-tools"); + const Utils::FilePath aaptToolPath = m_sdkLocation.pathAppended("build-tools"); QString toolPath = QString("%1/aapt").arg(buildToolsVersion().toString()); if (HostOsInfo::isWindowsHost()) toolPath += QTC_HOST_EXE_SUFFIX; - aaptToolPath.appendPath(toolPath); - return aaptToolPath; + return aaptToolPath.pathAppended(toolPath); } -FileName AndroidConfig::clangPath() const +FilePath AndroidConfig::clangPath() const { - FileName clangPath = m_ndkLocation; - clangPath.appendPath("toolchains/llvm/prebuilt/"); - FileName oldNdkClangPath = m_ndkLocation; - oldNdkClangPath.appendPath("toolchains/llvm-3.6/prebuilt/"); - const QVector<FileName> clangSearchPaths{clangPath, oldNdkClangPath}; + 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}; // detect toolchain host QStringList hostPatterns; @@ -421,54 +382,49 @@ FileName AndroidConfig::clangPath() const case OsTypeMac: hostPatterns << QLatin1String("darwin*"); break; - default: /* unknown host */ return FileName(); + default: /* unknown host */ return FilePath(); } - for (const FileName &path : clangSearchPaths) { + for (const FilePath &path : clangSearchPaths) { QDirIterator iter(path.toString(), hostPatterns, QDir::Dirs); if (iter.hasNext()) { iter.next(); - FileName found = path; - return found.appendPath(iter.fileName()) - .appendPath(HostOsInfo::withExecutableSuffix("bin/clang")); + return path.pathAppended(iter.fileName()) + .pathAppended(HostOsInfo::withExecutableSuffix("bin/clang")); } } return {}; } -FileName AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const +FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const { - FileName path = m_ndkLocation; - path.appendPath(QString("prebuilt/%1/bin/gdb%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); + const FilePath path = m_ndkLocation.pathAppended( + QString("prebuilt/%1/bin/gdb%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); if (path.exists()) return path; // fallback for old NDKs (e.g. 10e) - path = m_ndkLocation; - path.appendPath( - QString("toolchains/%1-4.9/prebuilt/%2/bin/%3-gdb%4") + return m_ndkLocation.pathAppended(QString("toolchains/%1-4.9/prebuilt/%2/bin/%3-gdb%4") .arg(toolchainPrefix(abi), toolchainHost(), toolsPrefix(abi), QTC_HOST_EXE_SUFFIX)); - return path; } -FileName AndroidConfig::makePath() const +FilePath AndroidConfig::makePath() const { - FileName path = m_ndkLocation; - path.appendPath(QString("prebuilt/%1/bin/make%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); - return path; + return m_ndkLocation.pathAppended( + QString("prebuilt/%1/bin/make%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); } -FileName AndroidConfig::openJDKBinPath() const +FilePath AndroidConfig::openJDKBinPath() const { - FileName path = m_openJDKLocation; + const FilePath path = m_openJDKLocation; if (!path.isEmpty()) - return path.appendPath(QLatin1String("bin")); + return path.pathAppended("bin"); return path; } -FileName AndroidConfig::keytoolPath() const +FilePath AndroidConfig::keytoolPath() const { - return openJDKBinPath().appendPath(keytoolName); + return openJDKBinPath().pathAppended(keytoolName); } QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const @@ -729,12 +685,12 @@ QString AndroidConfig::bestNdkPlatformMatch(int target) const return QString("android-%1").arg(AndroidManager::apiLevelRange().first); } -FileName AndroidConfig::sdkLocation() const +FilePath AndroidConfig::sdkLocation() const { return m_sdkLocation; } -void AndroidConfig::setSdkLocation(const FileName &sdkLocation) +void AndroidConfig::setSdkLocation(const FilePath &sdkLocation) { m_sdkLocation = sdkLocation; } @@ -743,8 +699,8 @@ QVersionNumber AndroidConfig::sdkToolsVersion() const { QVersionNumber version; if (m_sdkLocation.exists()) { - Utils::FileName sdkToolsPropertiesPath(m_sdkLocation); - sdkToolsPropertiesPath.appendPath("tools/source.properties"); + const Utils::FilePath sdkToolsPropertiesPath + = m_sdkLocation.pathAppended("tools/source.properties"); QSettings settings(sdkToolsPropertiesPath.toString(), QSettings::IniFormat); auto versionStr = settings.value(sdkToolsVersionKey).toString(); version = QVersionNumber::fromString(versionStr); @@ -755,9 +711,7 @@ QVersionNumber AndroidConfig::sdkToolsVersion() const QVersionNumber AndroidConfig::buildToolsVersion() const { QVersionNumber maxVersion; - Utils::FileName buildtoolsDir = m_sdkLocation; - buildtoolsDir.appendPath("build-tools"); - QDir buildToolsDir(buildtoolsDir.toString()); + QDir buildToolsDir(m_sdkLocation.pathAppended("build-tools").toString()); for (const QFileInfo &file: buildToolsDir.entryList(QDir::Dirs|QDir::NoDotAndDotDot)) maxVersion = qMax(maxVersion, QVersionNumber::fromString(file.fileName())); return maxVersion; @@ -774,7 +728,7 @@ void AndroidConfig::setSdkManagerToolArgs(const QStringList &args) m_sdkManagerToolArgs = args; } -FileName AndroidConfig::ndkLocation() const +FilePath AndroidConfig::ndkLocation() const { return m_ndkLocation; } @@ -790,10 +744,10 @@ static inline QString gdbServerArch(const Abi &abi) }; } -FileName AndroidConfig::gdbServer(const ProjectExplorer::Abi &abi) const +FilePath AndroidConfig::gdbServer(const ProjectExplorer::Abi &abi) const { - FileName path = AndroidConfigurations::currentConfig().ndkLocation(); - path.appendPath(QString::fromLatin1("prebuilt/android-%1/gdbserver/gdbserver") + const FilePath path = AndroidConfigurations::currentConfig().ndkLocation() + .pathAppended(QString("prebuilt/android-%1/gdbserver/gdbserver") .arg(gdbServerArch(abi))); if (path.exists()) return path; @@ -809,8 +763,7 @@ QVersionNumber AndroidConfig::ndkVersion() const return version; } - Utils::FileName ndkPropertiesPath(m_ndkLocation); - ndkPropertiesPath.appendPath("source.properties"); + const FilePath ndkPropertiesPath = m_ndkLocation.pathAppended("source.properties"); if (ndkPropertiesPath.exists()) { // source.properties files exists in NDK version > 11 QSettings settings(ndkPropertiesPath.toString(), QSettings::IniFormat); @@ -818,8 +771,7 @@ QVersionNumber AndroidConfig::ndkVersion() const version = QVersionNumber::fromString(versionStr); } else { // No source.properties. There should be a file named RELEASE.TXT - Utils::FileName ndkReleaseTxtPath(m_ndkLocation); - ndkReleaseTxtPath.appendPath("RELEASE.TXT"); + const FilePath ndkReleaseTxtPath = m_ndkLocation.pathAppended("RELEASE.TXT"); Utils::FileReader reader; QString errorString; if (reader.fetch(ndkReleaseTxtPath.toString(), &errorString)) { @@ -847,28 +799,28 @@ QVersionNumber AndroidConfig::ndkVersion() const return version; } -void AndroidConfig::setNdkLocation(const FileName &ndkLocation) +void AndroidConfig::setNdkLocation(const FilePath &ndkLocation) { m_ndkLocation = ndkLocation; m_NdkInformationUpToDate = false; } -FileName AndroidConfig::openJDKLocation() const +FilePath AndroidConfig::openJDKLocation() const { return m_openJDKLocation; } -void AndroidConfig::setOpenJDKLocation(const FileName &openJDKLocation) +void AndroidConfig::setOpenJDKLocation(const FilePath &openJDKLocation) { m_openJDKLocation = openJDKLocation; } -FileName AndroidConfig::keystoreLocation() const +FilePath AndroidConfig::keystoreLocation() const { return m_keystoreLocation; } -void AndroidConfig::setKeystoreLocation(const FileName &keystoreLocation) +void AndroidConfig::setKeystoreLocation(const FilePath &keystoreLocation) { m_keystoreLocation = keystoreLocation; } @@ -899,12 +851,12 @@ void AndroidConfig::setAutomaticKitCreation(bool b) m_automaticKitCreation = b; } -FileName AndroidConfig::qtLiveApkPath() const +FilePath AndroidConfig::qtLiveApkPath() const { QString apkPathStr(defaultQtLiveApk); if (qEnvironmentVariableIsSet("QTC_QT_LIVE_APK_PATH")) apkPathStr = QString::fromLocal8Bit(qgetenv("QTC_QT_LIVE_APK_PATH")); - return Utils::FileName::fromString(apkPathStr); + return Utils::FilePath::fromString(apkPathStr); } /////////////////////////////////// @@ -974,17 +926,6 @@ static bool matchToolChain(const ToolChain *atc, const ToolChain *btc) return aatc->targetAbi() == abtc->targetAbi(); } -static bool matchKits(const Kit *a, const Kit *b) -{ - if (QtSupport::QtKitInformation::qtVersion(a) != QtSupport::QtKitInformation::qtVersion(b)) - return false; - - return matchToolChain(ToolChainKitInformation::toolChain(a, ProjectExplorer::Constants::CXX_LANGUAGE_ID), - ToolChainKitInformation::toolChain(b, ProjectExplorer::Constants::CXX_LANGUAGE_ID)) - && matchToolChain(ToolChainKitInformation::toolChain(a, ProjectExplorer::Constants::C_LANGUAGE_ID), - ToolChainKitInformation::toolChain(b, ProjectExplorer::Constants::C_LANGUAGE_ID)); -} - void AndroidConfigurations::registerNewToolChains() { const QList<ToolChain *> existingAndroidToolChains @@ -1006,11 +947,11 @@ void AndroidConfigurations::removeOldToolChains() static QVariant findOrRegisterDebugger(ToolChain *tc) { - const FileName command = tc->suggestedDebugger(); + const FilePath command = tc->suggestedDebugger(); // 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() - && existing->abis() == QList<Abi>{tc->targetAbi()}) + && existing->abis() == Abis{tc->targetAbi()}) return existing->id(); // debugger not found, register a new one Debugger::DebuggerItem debugger; @@ -1026,11 +967,23 @@ static QVariant findOrRegisterDebugger(ToolChain *tc) void AndroidConfigurations::updateAutomaticKitList() { + const QList<Kit *> androidKits = Utils::filtered(KitManager::kits(), [](Kit *k) { + Core::Id deviceTypeId = DeviceTypeKitAspect::deviceTypeId(k); + return deviceTypeId == Core::Id(Constants::ANDROID_DEVICE_TYPE); + }); + + for (auto k: androidKits) { + if (k->value(Constants::ANDROID_KIT_NDK).isNull() || k->value(Constants::ANDROID_KIT_SDK).isNull()) { + k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString()); + k->setValue(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); + } + } + const QList<Kit *> existingKits = Utils::filtered(KitManager::kits(), [](Kit *k) { - Core::Id deviceTypeId = DeviceTypeKitInformation::deviceTypeId(k); + Core::Id deviceTypeId = DeviceTypeKitAspect::deviceTypeId(k); if (k->isAutoDetected() && !k->isSdkProvided() && deviceTypeId == Core::Id(Constants::ANDROID_DEVICE_TYPE)) { - if (!QtSupport::QtKitInformation::qtVersion(k)) + if (!QtSupport::QtKitAspect::qtVersion(k)) KitManager::deregisterKit(k); // Remove autoDetected kits without Qt. else return true; @@ -1044,7 +997,7 @@ void AndroidConfigurations::updateAutomaticKitList() return v->type() == Constants::ANDROIDQT; }); for (const QtSupport::BaseQtVersion *qtVersion : qtVersions) { - const QList<Abi> qtAbis = qtVersion->qtAbis(); + const Abis qtAbis = qtVersion->qtAbis(); if (qtAbis.empty()) continue; qtVersionsForArch[qtAbis.first()].append(qtVersion); @@ -1073,41 +1026,42 @@ void AndroidConfigurations::updateAutomaticKitList() return tc->targetAbi() == otherTc->targetAbi(); }); - auto initBasicKitData = [allLanguages, device](Kit *k, const QtSupport::BaseQtVersion *qt) { - k->setAutoDetected(true); - k->setAutoDetectionSource("AndroidConfiguration"); - DeviceTypeKitInformation::setDeviceTypeId(k, Core::Id(Constants::ANDROID_DEVICE_TYPE)); - for (ToolChain *tc : allLanguages) - ToolChainKitInformation::setToolChain(k, tc); - QtSupport::QtKitInformation::setQtVersion(k, qt); - DeviceKitInformation::setDevice(k, device); - }; + QHash<Core::Id, ToolChain *> toolChainForLanguage; + for (ToolChain *tc : allLanguages) + toolChainForLanguage[tc->language()] = tc; for (const QtSupport::BaseQtVersion *qt : qtVersionsForArch.value(tc->targetAbi())) { - auto newKit = std::make_unique<Kit>(); - Kit *toSetup = newKit.get(); - initBasicKitData(toSetup, qt); - Kit *existingKit = Utils::findOrDefault(existingKits, [toSetup](const Kit *k) { - return matchKits(toSetup, k); + Kit *existingKit = Utils::findOrDefault(existingKits, [&](const Kit *b) { + if (qt != QtSupport::QtKitAspect::qtVersion(b)) + return false; + return matchToolChain(toolChainForLanguage[ProjectExplorer::Constants::CXX_LANGUAGE_ID], + ToolChainKitAspect::toolChain(b, ProjectExplorer::Constants::CXX_LANGUAGE_ID)) + && matchToolChain(toolChainForLanguage[ProjectExplorer::Constants::C_LANGUAGE_ID], + ToolChainKitAspect::toolChain(b, ProjectExplorer::Constants::C_LANGUAGE_ID)); }); - if (existingKit) { - // Existing kit found. - // Update the existing kit with new data. - initBasicKitData(existingKit, qt); - newKit.reset(); - toSetup = existingKit; - } - - Debugger::DebuggerKitInformation::setDebugger(toSetup, findOrRegisterDebugger(tc)); - AndroidGdbServerKitInformation::setGdbSever(toSetup, currentConfig().gdbServer(tc->targetAbi())); - toSetup->makeSticky(); - - toSetup->setUnexpandedDisplayName(tr("Android for %1 (Clang %2)") - .arg(static_cast<const AndroidQtVersion *>(qt)->targetArch()) - .arg(qt->displayName())); - if (!existingKit) - KitManager::registerKit(std::move(newKit)); + const auto initializeKit = [allLanguages, device, tc, qt](Kit *k) { + k->setAutoDetected(true); + k->setAutoDetectionSource("AndroidConfiguration"); + DeviceTypeKitAspect::setDeviceTypeId(k, Core::Id(Constants::ANDROID_DEVICE_TYPE)); + for (ToolChain *tc : allLanguages) + ToolChainKitAspect::setToolChain(k, tc); + 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(qt->displayName())); + k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString()); + k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); + }; + + if (existingKit) + initializeKit(existingKit); // Update the existing kit with new data. + else + KitManager::registerKit(initializeKit); } } } @@ -1120,12 +1074,10 @@ bool AndroidConfigurations::force32bitEmulator() QProcessEnvironment AndroidConfigurations::toolsEnvironment(const AndroidConfig &config) { Environment env = Environment::systemEnvironment(); - Utils::FileName jdkLocation = config.openJDKLocation(); + Utils::FilePath jdkLocation = config.openJDKLocation(); if (!jdkLocation.isEmpty()) { env.set("JAVA_HOME", jdkLocation.toUserOutput()); - Utils::FileName binPath = jdkLocation; - binPath.appendPath("bin"); - env.prependOrSetPath(binPath.toUserOutput()); + env.prependOrSetPath(jdkLocation.pathAppended("bin").toUserOutput()); } return env.toProcessEnvironment(); } @@ -1195,7 +1147,7 @@ AndroidConfigurations::AndroidConfigurations() AndroidConfigurations::~AndroidConfigurations() = default; -static FileName javaHomeForJavac(const FileName &location) +static FilePath javaHomeForJavac(const FilePath &location) { QFileInfo fileInfo = location.toFileInfo(); int tries = 5; @@ -1203,14 +1155,14 @@ static FileName javaHomeForJavac(const FileName &location) QDir dir = fileInfo.dir(); dir.cdUp(); if (QFileInfo::exists(dir.filePath(QLatin1String("lib/tools.jar")))) - return FileName::fromString(dir.path()); + return FilePath::fromString(dir.path()); if (fileInfo.isSymLink()) fileInfo.setFile(fileInfo.symLinkTarget()); else break; --tries; } - return FileName(); + return FilePath(); } void AndroidConfigurations::load() @@ -1223,7 +1175,7 @@ void AndroidConfigurations::load() if (m_config.openJDKLocation().isEmpty()) { if (HostOsInfo::isLinuxHost()) { Environment env = Environment::systemEnvironment(); - FileName location = env.searchInPath(QLatin1String("javac")); + FilePath location = env.searchInPath(QLatin1String("javac")); QFileInfo fi = location.toFileInfo(); if (fi.exists() && fi.isExecutable() && !fi.isDir()) { m_config.setOpenJDKLocation(javaHomeForJavac(location)); @@ -1239,7 +1191,7 @@ void AndroidConfigurations::load() if (response.result == SynchronousProcessResponse::Finished) { const QString &javaHome = response.allOutput().trimmed(); if (!javaHome.isEmpty() && QFileInfo::exists(javaHome)) - m_config.setOpenJDKLocation(FileName::fromString(javaHome)); + m_config.setOpenJDKLocation(FilePath::fromString(javaHome)); } } } else if (HostOsInfo::isWindowsHost()) { @@ -1281,7 +1233,7 @@ void AndroidConfigurations::load() } } if (!javaHome.isEmpty()) { - m_config.setOpenJDKLocation(FileName::fromString(javaHome)); + m_config.setOpenJDKLocation(FilePath::fromString(javaHome)); saveSettings = true; } } diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 70d97c129c..3b9ecb4bb1 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -52,7 +52,6 @@ class Project; namespace Android { - namespace Internal { class AndroidSdkManager; class AndroidPluginPrivate; @@ -98,23 +97,23 @@ public: static QStringList apiLevelNamesFor(const SdkPlatformList &platforms); static QString apiLevelNameFor(const SdkPlatform *platform); - Utils::FileName sdkLocation() const; - void setSdkLocation(const Utils::FileName &sdkLocation); + Utils::FilePath sdkLocation() const; + void setSdkLocation(const Utils::FilePath &sdkLocation); QVersionNumber sdkToolsVersion() const; QVersionNumber buildToolsVersion() const; QStringList sdkManagerToolArgs() const; void setSdkManagerToolArgs(const QStringList &args); - Utils::FileName ndkLocation() const; - Utils::FileName gdbServer(const ProjectExplorer::Abi &abi) const; + Utils::FilePath ndkLocation() const; + Utils::FilePath gdbServer(const ProjectExplorer::Abi &abi) const; QVersionNumber ndkVersion() const; - void setNdkLocation(const Utils::FileName &ndkLocation); + void setNdkLocation(const Utils::FilePath &ndkLocation); - Utils::FileName openJDKLocation() const; - void setOpenJDKLocation(const Utils::FileName &openJDKLocation); + Utils::FilePath openJDKLocation() const; + void setOpenJDKLocation(const Utils::FilePath &openJDKLocation); - Utils::FileName keystoreLocation() const; - void setKeystoreLocation(const Utils::FileName &keystoreLocation); + Utils::FilePath keystoreLocation() const; + void setKeystoreLocation(const Utils::FilePath &keystoreLocation); QString toolchainHost() const; @@ -124,20 +123,20 @@ public: bool automaticKitCreation() const; void setAutomaticKitCreation(bool b); - Utils::FileName qtLiveApkPath() const; + Utils::FilePath qtLiveApkPath() const; - Utils::FileName adbToolPath() const; - Utils::FileName androidToolPath() const; - Utils::FileName emulatorToolPath() const; - Utils::FileName sdkManagerToolPath() const; - Utils::FileName avdManagerToolPath() const; - Utils::FileName aaptToolPath() const; + Utils::FilePath adbToolPath() const; + Utils::FilePath androidToolPath() const; + Utils::FilePath emulatorToolPath() const; + Utils::FilePath sdkManagerToolPath() const; + Utils::FilePath avdManagerToolPath() const; + Utils::FilePath aaptToolPath() const; - Utils::FileName clangPath() const; - Utils::FileName gdbPath(const ProjectExplorer::Abi &abi) const; - Utils::FileName makePath() const; + Utils::FilePath clangPath() const; + Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi) const; + Utils::FilePath makePath() const; - Utils::FileName keytoolPath() const; + Utils::FilePath keytoolPath() const; QVector<AndroidDeviceInfo> connectedDevices(QString *error = nullptr) const; static QVector<AndroidDeviceInfo> connectedDevices(const QString &adbToolPath, QString *error = nullptr); @@ -159,7 +158,7 @@ public: private: static QString getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property); - Utils::FileName openJDKBinPath() const; + Utils::FilePath openJDKBinPath() const; int getSDKVersion(const QString &device) const; static int getSDKVersion(const QString &adbToolPath, const QString &device); QStringList getAbis(const QString &device) const; @@ -170,11 +169,11 @@ private: void updateNdkInformation() const; - Utils::FileName m_sdkLocation; + Utils::FilePath m_sdkLocation; QStringList m_sdkManagerToolArgs; - Utils::FileName m_ndkLocation; - Utils::FileName m_openJDKLocation; - Utils::FileName m_keystoreLocation; + Utils::FilePath m_ndkLocation; + Utils::FilePath m_openJDKLocation; + Utils::FilePath m_keystoreLocation; unsigned m_partitionSize = 1024; bool m_automaticKitCreation = true; diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h index ee2630c198..f34da07f4e 100644 --- a/src/plugins/android/androidconstants.h +++ b/src/plugins/android/androidconstants.h @@ -63,23 +63,34 @@ const char ANDROID_MANIFEST_MIME_TYPE[] = "application/vnd.google.android.androi const char ANDROID_MANIFEST_EDITOR_ID[] = "Android.AndroidManifestEditor.Id"; const char ANDROID_MANIFEST_EDITOR_CONTEXT[] = "Android.AndroidManifestEditor.Id"; +const char ANDROID_KIT_NDK[] = "Android.NDK"; +const char ANDROID_KIT_SDK[] = "Android.SDK"; + const char ANDROID_BUILDDIRECTORY[] = "android-build"; const char JAVA_EDITOR_ID[] = "java.editor"; const char JAVA_MIMETYPE[] = "text/x-java"; const char ANDROID_ARCHITECTURE[] = "Android.Architecture"; -const char ANDROID_DEPLOY_SETTINGS_FILE[] = "AndroidDeploySettingsFile"; const char ANDROID_PACKAGE_SOURCE_DIR[] = "AndroidPackageSourceDir"; const char ANDROID_EXTRA_LIBS[] = "AndroidExtraLibs"; const char ANDROID_PACKAGENAME[] = "Android.PackageName"; -const char ANDROID_PACKAGE_INSTALLATION_STEP_ID[] = "Qt4ProjectManager.AndroidPackageInstallationStep"; +const char ANDROID_PACKAGE_INSTALLATION_STEP_ID[] + = "Qt4ProjectManager.AndroidPackageInstallationStep"; const char ANDROID_BUILD_APK_ID[] = "QmakeProjectManager.AndroidBuildApkStep"; const char AndroidPackageSourceDir[] = "AndroidPackageSourceDir"; // QString const char AndroidDeploySettingsFile[] = "AndroidDeploySettingsFile"; // QString const char AndroidExtraLibs[] = "AndroidExtraLibs"; // QStringList +// REMOVE ME const char AndroidArch[] = "AndroidArch"; // QString const char AndroidSoLibPath[] = "AndroidSoLibPath"; // QStringList +const char AndroidTargets[] = "AndroidTargets"; // QStringList +const char AndroidApk[] = "Android.APK"; // QStringList +const char AndroidManifest[] = "Android.Manifest"; // QStringList + +const char AndroidNdkPlatform[] = "AndroidNdkPlatform"; //QString +const char NdkLocation[] = "NdkLocation"; // FileName +const char AndroidABI[] = "AndroidABI"; // QString } // namespace Constants; } // namespace Android diff --git a/src/plugins/android/androidcreatekeystorecertificate.cpp b/src/plugins/android/androidcreatekeystorecertificate.cpp index dd2906e575..1ac6e1ea12 100644 --- a/src/plugins/android/androidcreatekeystorecertificate.cpp +++ b/src/plugins/android/androidcreatekeystorecertificate.cpp @@ -58,7 +58,7 @@ AndroidCreateKeystoreCertificate::~AndroidCreateKeystoreCertificate() delete ui; } -Utils::FileName AndroidCreateKeystoreCertificate::keystoreFilePath() +Utils::FilePath AndroidCreateKeystoreCertificate::keystoreFilePath() { return m_keystoreFilePath; } @@ -152,7 +152,7 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted() if (!validateUserInput()) return; - m_keystoreFilePath = Utils::FileName::fromString(QFileDialog::getSaveFileName(this, tr("Keystore Filename"), + m_keystoreFilePath = Utils::FilePath::fromString(QFileDialog::getSaveFileName(this, tr("Keystore Filename"), QDir::homePath() + QLatin1String("/android_release.keystore"), tr("Keystore files (*.keystore *.jks)"))); if (m_keystoreFilePath.isEmpty()) diff --git a/src/plugins/android/androidcreatekeystorecertificate.h b/src/plugins/android/androidcreatekeystorecertificate.h index 86c9f36fcf..4a9cbe9c42 100644 --- a/src/plugins/android/androidcreatekeystorecertificate.h +++ b/src/plugins/android/androidcreatekeystorecertificate.h @@ -49,7 +49,7 @@ class AndroidCreateKeystoreCertificate : public QDialog public: explicit AndroidCreateKeystoreCertificate(QWidget *parent = nullptr); ~AndroidCreateKeystoreCertificate() override; - Utils::FileName keystoreFilePath(); + Utils::FilePath keystoreFilePath(); QString keystorePassword(); QString certificateAlias(); QString certificatePassword(); @@ -69,7 +69,7 @@ private slots: private: bool validateUserInput(); Ui::AndroidCreateKeystoreCertificate *ui; - Utils::FileName m_keystoreFilePath; + Utils::FilePath m_keystoreFilePath; }; } // namespace Internal diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 2af97bdffd..a703c31936 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -29,6 +29,7 @@ #include "androidglobal.h" #include "androidrunner.h" #include "androidmanager.h" +#include "androidqtversion.h" #include <debugger/debuggerkitinformation.h> #include <debugger/debuggerrunconfigurationaspect.h> @@ -92,10 +93,8 @@ static QStringList uniquePaths(const QStringList &files) return paths.toList(); } -static QStringList getSoLibSearchPath(const RunConfiguration *rc) +static QStringList getSoLibSearchPath(const ProjectNode *node) { - Target *target = rc->target(); - const ProjectNode *node = target->project()->findNodeForBuildKey(rc->buildKey()); if (!node) return {}; @@ -121,12 +120,10 @@ static QStringList getSoLibSearchPath(const RunConfiguration *rc) return res; } -static QStringList getExtraLibs(const RunConfiguration *rc) +static QStringList getExtraLibs(const ProjectNode *node) { - const ProjectNode *node = rc->target()->project()->findNodeForBuildKey(rc->buildKey()); if (!node) return {}; - return node->data(Android::Constants::AndroidExtraLibs).toStringList(); } @@ -149,8 +146,7 @@ AndroidDebugSupport::AndroidDebugSupport(RunControl *runControl, const QString & void AndroidDebugSupport::start() { - auto runConfig = runControl()->runConfiguration(); - Target *target = runConfig->target(); + Target *target = runControl()->target(); Kit *kit = target->kit(); setStartMode(AttachToRemoteServer); @@ -167,14 +163,17 @@ void AndroidDebugSupport::start() setUseTargetAsync(true); } - QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(kit); + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit); if (isCppDebugging()) { qCDebug(androidDebugSupportLog) << "C++ debugging enabled"; - QStringList solibSearchPath = getSoLibSearchPath(runConfig); - QStringList extraLibs = getExtraLibs(runConfig); + const ProjectNode *node = target->project()->findNodeForBuildKey(runControl()->buildKey()); + QStringList solibSearchPath = getSoLibSearchPath(node); + QStringList extraLibs = getExtraLibs(node); solibSearchPath.append(qtSoPaths(qtVersion)); solibSearchPath.append(uniquePaths(extraLibs)); + solibSearchPath.append(target->activeBuildConfiguration()->buildDirectory().toString()); + solibSearchPath.removeDuplicates(); setSolibSearchPath(solibSearchPath); qCDebug(androidDebugSupportLog) << "SoLibSearchPath: "<<solibSearchPath; setSymbolFile(target->activeBuildConfiguration()->buildDirectory().toString() @@ -186,12 +185,15 @@ void AndroidDebugSupport::start() gdbServer.setPort(m_runner->gdbServerPort().number()); setRemoteChannel(gdbServer); - int sdkVersion = qMax(AndroidManager::minimumSDK(target->kit()), - AndroidManager::minimumNDK(target->kit())); - Utils::FileName sysRoot = AndroidConfigurations::currentConfig().ndkLocation() - .appendPath("platforms") - .appendPath(QString("android-%1").arg(sdkVersion)) - .appendPath(toNdkArch(AndroidManager::targetArch(target))); + auto qt = static_cast<AndroidQtVersion *>(qtVersion); + QTC_CHECK(qt); + const int minimumNdk = qt ? qt->minimumNDK() : 0; + + int sdkVersion = qMax(AndroidManager::minimumSDK(kit), minimumNdk); + Utils::FilePath sysRoot = AndroidConfigurations::currentConfig().ndkLocation() + .pathAppended("platforms") + .pathAppended(QString("android-%1").arg(sdkVersion)) + .pathAppended(toNdkArch(AndroidManager::targetArch(target))); setSysRoot(sysRoot); qCDebug(androidDebugSupportLog) << "Sysroot: " << sysRoot; } diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 1de24c76e7..42a3c7d6e0 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -63,8 +63,10 @@ #include <QVBoxLayout> using namespace ProjectExplorer; -using namespace Android; -using namespace Android::Internal; +using namespace Utils; + +namespace Android { +namespace Internal { namespace { Q_LOGGING_CATEGORY(deployStepLog, "qtc.android.build.androiddeployqtstep", QtWarningMsg) @@ -149,7 +151,7 @@ AndroidDeployQtStep::AndroidDeployQtStep(ProjectExplorer::BuildStepList *parent) : ProjectExplorer::BuildStep(parent, stepId()) { setImmutable(true); - m_uninstallPreviousPackage = QtSupport::QtKitInformation::qtVersion(target()->kit())->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0); + m_uninstallPreviousPackage = QtSupport::QtKitAspect::qtVersion(target()->kit())->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0); //: AndroidDeployQtStep default display name setDefaultDisplayName(tr("Deploy to Android device")); @@ -169,7 +171,7 @@ Core::Id AndroidDeployQtStep::stepId() bool AndroidDeployQtStep::init() { - m_androiddeployqtArgs.clear(); + m_androiddeployqtArgs = CommandLine(); m_targetArch = AndroidManager::targetArch(target()); if (m_targetArch.isEmpty()) { @@ -186,11 +188,6 @@ bool AndroidDeployQtStep::init() QTC_ASSERT(deployQtLive || bc, return false); auto androidBuildApkStep = AndroidBuildApkStep::findInBuild(bc); - if (!androidBuildApkStep && !deployQtLive) { - emit addOutput(tr("Cannot find the android build step."), OutputFormat::Stderr); - return false; - } - int minTargetApi = AndroidManager::minimumSDK(target()); qCDebug(deployStepLog) << "Target architecture:" << m_targetArch << "Min target API" << minTargetApi; @@ -224,7 +221,7 @@ bool AndroidDeployQtStep::init() emit addOutput(tr("Deploying to %1").arg(m_serialNumber), OutputFormat::Stdout); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target()->kit()); if (!version) return false; @@ -236,60 +233,60 @@ bool AndroidDeployQtStep::init() version->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0); if (m_useAndroiddeployqt) { - m_command = version->qmakeProperty("QT_HOST_BINS"); - if (m_command.isEmpty()) { - emit addOutput(tr("Cannot find the androiddeployqt tool."), OutputFormat::Stderr); - return false; - } - qCDebug(deployStepLog) << "Using androiddeployqt"; - if (!m_command.endsWith(QLatin1Char('/'))) - m_command += QLatin1Char('/'); - m_command += Utils::HostOsInfo::withExecutableSuffix(QLatin1String("androiddeployqt")); - - 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")); - - QString jsonFile; - if (const ProjectNode *node = target()->project()->findNodeForBuildKey(rc->buildKey())) - jsonFile = node->data(Constants::AndroidDeploySettingsFile).toString(); - if (jsonFile.isEmpty()) { - emit addOutput(tr("Cannot find the androiddeploy Json file."), OutputFormat::Stderr); + const ProjectNode *node = target()->project()->findNodeForBuildKey(rc->buildKey()); + if (!node) return false; - } + m_apkPath = Utils::FilePath::fromString(node->data(Constants::AndroidApk).toString()); + if (!m_apkPath.isEmpty()) { + m_manifestName = Utils::FilePath::fromString(node->data(Constants::AndroidManifest).toString()); + m_command = AndroidConfigurations::currentConfig().adbToolPath(); + AndroidManager::setManifestPath(target(), m_manifestName); + } else { + QString jsonFile = node->data(Constants::AndroidDeploySettingsFile).toString(); + if (jsonFile.isEmpty()) { + emit addOutput(tr("Cannot find the androiddeploy Json file."), OutputFormat::Stderr); + return false; + } + m_command = FilePath::fromString(version->qmakeProperty("QT_HOST_BINS")); + if (m_command.isEmpty()) { + emit addOutput(tr("Cannot find the androiddeployqt tool."), OutputFormat::Stderr); + return false; + } + qCDebug(deployStepLog) << "Using androiddeployqt"; + m_command = m_command.pathAppended(HostOsInfo::withExecutableSuffix("androiddeployqt")); - Utils::QtcProcess::addArg(&m_androiddeployqtArgs, jsonFile); - if (androidBuildApkStep && androidBuildApkStep->useMinistro()) { - qCDebug(deployStepLog) << "Using ministro"; - Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--deployment")); - Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("ministro")); - } + m_workingDirectory = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY); - Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--gradle")); + m_androiddeployqtArgs.addArgs({"--verbose", + "--output", m_workingDirectory.toString(), + "--no-build", + "--input", jsonFile}); - if (androidBuildApkStep && 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")); + if (androidBuildApkStep && androidBuildApkStep->useMinistro()) { + qCDebug(deployStepLog) << "Using ministro"; + m_androiddeployqtArgs.addArgs({"--deployment", "ministro"}); + } + + m_androiddeployqtArgs.addArg("--gradle"); + + if (androidBuildApkStep && 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. + m_androiddeployqtArgs.addArgs({"--sign", "foo", "bar"}); + } } } else { m_uninstallPreviousPackageRun = true; - m_command = AndroidConfigurations::currentConfig().adbToolPath().toString(); + m_command = AndroidConfigurations::currentConfig().adbToolPath(); const AndroidConfig &config = AndroidConfigurations::currentConfig(); m_apkPath = deployQtLive ? config.qtLiveApkPath() : AndroidManager::apkPath(target()); - m_workingDirectory = bc ? bc->buildDirectory().toString() : QString(); + m_workingDirectory = bc ? bc->buildDirectory() : FilePath(); } m_environment = bc ? bc->environment() : Utils::Environment(); - m_adbPath = AndroidConfigurations::currentConfig().adbToolPath().toString(); + m_adbPath = AndroidConfigurations::currentConfig().adbToolPath(); AndroidAvdManager avdManager; // Start the AVD if not running. @@ -300,18 +297,17 @@ bool AndroidDeployQtStep::init() AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy() { - QString args; - if (m_useAndroiddeployqt) { - args = m_androiddeployqtArgs; + CommandLine cmd(m_command, {}); + if (m_useAndroiddeployqt && m_apkPath.isEmpty()) { + cmd.addArgs(m_androiddeployqtArgs.arguments()); if (m_uninstallPreviousPackageRun) - Utils::QtcProcess::addArg(&args, QLatin1String("--install")); + cmd.addArg("--install"); else - Utils::QtcProcess::addArg(&args, QLatin1String("--reinstall")); + cmd.addArg("--reinstall"); + + if (!m_serialNumber.isEmpty() && !m_serialNumber.startsWith("????")) + cmd.addArgs({"--device", m_serialNumber}); - if (!m_serialNumber.isEmpty() && !m_serialNumber.startsWith(QLatin1String("????"))) { - Utils::QtcProcess::addArg(&args, QLatin1String("--device")); - Utils::QtcProcess::addArg(&args, m_serialNumber); - } } else { RunConfiguration *rc = target()->activeRunConfiguration(); QTC_ASSERT(rc, return DeployErrorCode::Failure); @@ -349,22 +345,18 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy() } qCDebug(deployStepLog) << "Uninstalling previous package"; emit addOutput(tr("Uninstall previous package %1.").arg(packageName), OutputFormat::NormalMessage); - runCommand(m_adbPath, + runCommand(m_adbPath.toString(), AndroidDeviceInfo::adbSelector(m_serialNumber) << QLatin1String("uninstall") << packageName); } - foreach (const QString &arg, AndroidDeviceInfo::adbSelector(m_serialNumber)) - Utils::QtcProcess::addArg(&args, arg); - - Utils::QtcProcess::addArg(&args, QLatin1String("install")); - Utils::QtcProcess::addArg(&args, QLatin1String("-r")); - Utils::QtcProcess::addArg(&args, m_apkPath.toString()); + cmd.addArgs(AndroidDeviceInfo::adbSelector(m_serialNumber)); + cmd.addArgs({"install", "-r", m_apkPath.toString()}); } m_process = new Utils::QtcProcess; - m_process->setCommand(m_command, args); - m_process->setWorkingDirectory(m_workingDirectory); + m_process->setCommand(cmd); + m_process->setWorkingDirectory(m_workingDirectory.toString()); m_process->setEnvironment(m_environment); if (Utils::HostOsInfo::isWindowsHost()) @@ -378,8 +370,7 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy() m_process->start(); - emit addOutput(tr("Starting: \"%1\" %2") - .arg(QDir::toNativeSeparators(m_command), args), + emit addOutput(tr("Starting: \"%1\"").arg(cmd.toUserOutput()), BuildStep::OutputFormat::NormalMessage); while (!m_process->waitForFinished(200)) { @@ -410,14 +401,15 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy() m_process = nullptr; if (exitStatus == QProcess::NormalExit && exitCode == 0) { - emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command), + emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command.toUserOutput()), BuildStep::OutputFormat::NormalMessage); } else if (exitStatus == QProcess::NormalExit) { emit addOutput(tr("The process \"%1\" exited with code %2.") - .arg(m_command, QString::number(exitCode)), + .arg(m_command.toUserOutput(), QString::number(exitCode)), BuildStep::OutputFormat::ErrorMessage); } else { - emit addOutput(tr("The process \"%1\" crashed.").arg(m_command), BuildStep::OutputFormat::ErrorMessage); + emit addOutput(tr("The process \"%1\" crashed.").arg(m_command.toUserOutput()), + BuildStep::OutputFormat::ErrorMessage); } if (deployError != NoError) { @@ -497,7 +489,7 @@ bool AndroidDeployQtStep::runImpl() for (auto itr = m_filesToPull.constBegin(); itr != m_filesToPull.constEnd(); ++itr) { QFile::remove(itr.value()); - runCommand(m_adbPath, + runCommand(m_adbPath.toString(), AndroidDeviceInfo::adbSelector(m_serialNumber) << "pull" << itr.key() << itr.value()); if (!QFileInfo::exists(itr.value())) { @@ -527,7 +519,7 @@ void AndroidDeployQtStep::gatherFilesToPull() if (m_deviceInfo.cpuAbi.contains(QLatin1String("arm64-v8a")) || m_deviceInfo.cpuAbi.contains(QLatin1String("x86_64"))) { const Core::Id cxxLanguageId = ProjectExplorer::Constants::CXX_LANGUAGE_ID; - ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit(), cxxLanguageId); + ToolChain *tc = ToolChainKitAspect::toolChain(target()->kit(), cxxLanguageId); if (tc && tc->targetAbi().wordWidth() == 64) { m_filesToPull["/system/bin/app_process64"] = buildDir + "app_process"; libDirName = "lib64"; @@ -634,7 +626,10 @@ void AndroidDeployQtStep::setUninstallPreviousPackage(bool uninstall) AndroidDeployQtStep::UninstallType AndroidDeployQtStep::uninstallPreviousPackage() { - if (QtSupport::QtKitInformation::qtVersion(target()->kit())->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) + if (QtSupport::QtKitAspect::qtVersion(target()->kit())->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) return ForceUnintall; return m_uninstallPreviousPackage ? Uninstall : Keep; } + +} // Internal +} // Android diff --git a/src/plugins/android/androiddeployqtstep.h b/src/plugins/android/androiddeployqtstep.h index b2a831efe7..48faf2abf5 100644 --- a/src/plugins/android/androiddeployqtstep.h +++ b/src/plugins/android/androiddeployqtstep.h @@ -33,8 +33,7 @@ #include <qtsupport/baseqtversion.h> #include <utils/environment.h> - -namespace Utils { class QtcProcess; } +#include <utils/qtcprocess.h> namespace Android { namespace Internal { @@ -106,10 +105,10 @@ private: friend void operator|=(DeployErrorCode &e1, const DeployErrorCode &e2) { e1 = static_cast<AndroidDeployQtStep::DeployErrorCode>((int)e1 | (int)e2); } friend DeployErrorCode operator|(const DeployErrorCode &e1, const DeployErrorCode &e2) { return static_cast<AndroidDeployQtStep::DeployErrorCode>((int)e1 | (int)e2); } - Utils::FileName m_manifestName; + Utils::FilePath m_manifestName; QString m_serialNumber; QString m_avdName; - Utils::FileName m_apkPath; + Utils::FilePath m_apkPath; QMap<QString, QString> m_filesToPull; QString m_targetArch; @@ -118,10 +117,10 @@ private: bool m_useAndroiddeployqt = false; bool m_askForUninstall = false; static const Core::Id Id; - QString m_androiddeployqtArgs; - QString m_adbPath; - QString m_command; - QString m_workingDirectory; + Utils::CommandLine m_androiddeployqtArgs; + Utils::FilePath m_adbPath; + Utils::FilePath m_command; + Utils::FilePath m_workingDirectory; Utils::Environment m_environment; Utils::QtcProcess *m_process = nullptr; AndroidDeviceInfo m_deviceInfo; diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index e33c3e3d12..3803ac5073 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -90,11 +90,6 @@ Utils::OsType AndroidDevice::osType() const return Utils::OsTypeOtherUnix; } -IDevice::Ptr AndroidDevice::clone() const -{ - return IDevice::Ptr(new AndroidDevice(*this)); -} - QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const { QUrl url; @@ -103,5 +98,18 @@ QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const return url; } + +// Factory + +AndroidDeviceFactory::AndroidDeviceFactory() + : ProjectExplorer::IDeviceFactory(Constants::ANDROID_DEVICE_TYPE) +{ + setObjectName(QLatin1String("AndroidDeviceFactory")); + setDisplayName(tr("Android Device")); + setCombinedIcon(":/android/images/androiddevicesmall.png", + ":/android/images/androiddevice.png"); + setConstructionFunction(&AndroidDevice::create); +} + } // namespace Internal } // namespace Android diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h index 22a0e53df1..7a66e1d15c 100644 --- a/src/plugins/android/androiddevice.h +++ b/src/plugins/android/androiddevice.h @@ -26,6 +26,7 @@ #pragma once #include <projectexplorer/devicesupport/idevice.h> +#include <projectexplorer/devicesupport/idevicefactory.h> namespace Android { namespace Internal { @@ -46,9 +47,15 @@ private: ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override; Utils::OsType osType() const override; - ProjectExplorer::IDevice::Ptr clone() const override; QUrl toolControlChannel(const ControlChannelHint &) const override; }; +class AndroidDeviceFactory : public ProjectExplorer::IDeviceFactory +{ + Q_OBJECT +public: + AndroidDeviceFactory(); +}; + } // namespace Internal } // namespace Android diff --git a/src/plugins/android/androiddevicedialog.cpp b/src/plugins/android/androiddevicedialog.cpp index 529b2a066a..a0b786ad69 100644 --- a/src/plugins/android/androiddevicedialog.cpp +++ b/src/plugins/android/androiddevicedialog.cpp @@ -173,7 +173,7 @@ public: // topRight auto drawTopRight = [&](const QString text, const QFontMetrics &fm) { - painter->drawText(opt.rect.right() - fm.width(text) - 6 , 2 + opt.rect.top() + fm.ascent(), text); + painter->drawText(opt.rect.right() - fm.horizontalAdvance(text) - 6 , 2 + opt.rect.top() + fm.ascent(), text); }; if (device.type == AndroidDeviceInfo::Hardware) { diff --git a/src/plugins/android/androiddevicefactory.cpp b/src/plugins/android/androiddevicefactory.cpp deleted file mode 100644 index 19a4679491..0000000000 --- a/src/plugins/android/androiddevicefactory.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "androiddevicefactory.h" -#include "androiddevice.h" - -#include "androidconstants.h" - -namespace Android { -namespace Internal { - -AndroidDeviceFactory::AndroidDeviceFactory() - : ProjectExplorer::IDeviceFactory(Constants::ANDROID_DEVICE_TYPE) -{ - setObjectName(QLatin1String("AndroidDeviceFactory")); - setDisplayName(tr("Android Device")); - setCombinedIcon(":/android/images/androiddevicesmall.png", - ":/android/images/androiddevice.png"); - setConstructionFunction(&AndroidDevice::create); -} - -} // namespace Internal -} // namespace Android diff --git a/src/plugins/android/androiddevicefactory.h b/src/plugins/android/androiddevicefactory.h deleted file mode 100644 index 10e97bcd0e..0000000000 --- a/src/plugins/android/androiddevicefactory.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <projectexplorer/devicesupport/idevicefactory.h> - -namespace Android { -namespace Internal { - -class AndroidDeviceFactory : public ProjectExplorer::IDeviceFactory -{ - Q_OBJECT -public: - AndroidDeviceFactory(); -}; - -} // namespace Internal -} // namespace Android diff --git a/src/plugins/android/androidgdbserverkitinformation.cpp b/src/plugins/android/androidgdbserverkitinformation.cpp index d4a7e17d85..fdc5946c80 100644 --- a/src/plugins/android/androidgdbserverkitinformation.cpp +++ b/src/plugins/android/androidgdbserverkitinformation.cpp @@ -50,78 +50,96 @@ using namespace Utils; namespace Android { namespace Internal { -AndroidGdbServerKitInformation::AndroidGdbServerKitInformation() +class AndroidGdbServerKitAspectWidget : public KitAspectWidget { - setId(AndroidGdbServerKitInformation::id()); + Q_DECLARE_TR_FUNCTIONS(Android::Internal::AndroidGdbServerKitAspect) +public: + AndroidGdbServerKitAspectWidget(Kit *kit, const KitAspect *ki); + ~AndroidGdbServerKitAspectWidget() override; + + void makeReadOnly() override; + void refresh() override; + + QWidget *mainWidget() const override; + QWidget *buttonWidget() const override; + +private: + void autoDetectDebugger(); + void showDialog(); + + QLabel *m_label; + QPushButton *m_button; +}; + + +AndroidGdbServerKitAspect::AndroidGdbServerKitAspect() +{ + setId(AndroidGdbServerKitAspect::id()); + setDisplayName(tr("Android GDB server")); + setDescription(tr("The GDB server to use for this kit.")); setPriority(27999); // Just one less than Debugger! } -QVariant AndroidGdbServerKitInformation::defaultValue(const Kit *kit) const +void AndroidGdbServerKitAspect::setup(Kit *kit) { - return autoDetect(kit).toString(); + if (kit && !kit->hasValue(id())) + kit->setValue(id(), autoDetect(kit).toString()); } -QList<Task> AndroidGdbServerKitInformation::validate(const Kit *) const +Tasks AndroidGdbServerKitAspect::validate(const Kit *) const { - return QList<Task>(); + return {}; } -KitInformation::ItemList AndroidGdbServerKitInformation::toUserOutput(const Kit *kit) const +bool AndroidGdbServerKitAspect::isApplicableToKit(const Kit *k) const { - return KitInformation::ItemList() - << qMakePair(tr("GDB server"), AndroidGdbServerKitInformation::gdbServer(kit).toUserOutput()); + return DeviceKitAspect::deviceId(k) == Constants::ANDROID_DEVICE_ID; } -KitConfigWidget *AndroidGdbServerKitInformation::createConfigWidget(Kit *kit) const +KitAspect::ItemList AndroidGdbServerKitAspect::toUserOutput(const Kit *kit) const { - QTC_ASSERT(kit, return nullptr); - return new AndroidGdbServerKitInformationWidget(kit, this); + return {{tr("GDB server"), AndroidGdbServerKitAspect::gdbServer(kit).toUserOutput()}}; } -Core::Id AndroidGdbServerKitInformation::id() +KitAspectWidget *AndroidGdbServerKitAspect::createConfigWidget(Kit *kit) const { - return "Android.GdbServer.Information"; + QTC_ASSERT(kit, return nullptr); + return new AndroidGdbServerKitAspectWidget(kit, this); } -bool AndroidGdbServerKitInformation::isAndroidKit(const Kit *kit) +Core::Id AndroidGdbServerKitAspect::id() { - QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(kit); - ToolChain *tc = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); - if (qt && tc) - return qt->type() == QLatin1String(Constants::ANDROIDQT) - && tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID; - return false; - + return "Android.GdbServer.Information"; } -FileName AndroidGdbServerKitInformation::gdbServer(const Kit *kit) +FilePath AndroidGdbServerKitAspect::gdbServer(const Kit *kit) { - QTC_ASSERT(kit, return FileName()); - return FileName::fromString(kit->value(AndroidGdbServerKitInformation::id()).toString()); + QTC_ASSERT(kit, return FilePath()); + return FilePath::fromString(kit->value(AndroidGdbServerKitAspect::id()).toString()); } -void AndroidGdbServerKitInformation::setGdbSever(Kit *kit, const FileName &gdbServerCommand) +void AndroidGdbServerKitAspect::setGdbSever(Kit *kit, const FilePath &gdbServerCommand) { QTC_ASSERT(kit, return); - kit->setValue(AndroidGdbServerKitInformation::id(), gdbServerCommand.toString()); + kit->setValue(AndroidGdbServerKitAspect::id(), gdbServerCommand.toString()); } -FileName AndroidGdbServerKitInformation::autoDetect(const Kit *kit) +FilePath AndroidGdbServerKitAspect::autoDetect(const Kit *kit) { - ToolChain *tc = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + ToolChain *tc = ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_ID) - return FileName(); + return FilePath(); auto atc = static_cast<AndroidToolChain *>(tc); return atc->suggestedGdbServer(); } /////////////// -// AndroidGdbServerKitInformationWidget +// AndroidGdbServerKitAspectWidget /////////////// -AndroidGdbServerKitInformationWidget::AndroidGdbServerKitInformationWidget(Kit *kit, const KitInformation *ki) : - KitConfigWidget(kit, ki), +AndroidGdbServerKitAspectWidget::AndroidGdbServerKitAspectWidget(Kit *kit, const KitAspect *ki) : + KitAspectWidget(kit, ki), m_label(new ElidingLabel), m_button(new QPushButton(tr("Manage..."))) { @@ -129,62 +147,47 @@ AndroidGdbServerKitInformationWidget::AndroidGdbServerKitInformationWidget(Kit * auto buttonMenu = new QMenu(m_button); QAction *autoDetectAction = buttonMenu->addAction(tr("Auto-detect")); connect(autoDetectAction, &QAction::triggered, - this, &AndroidGdbServerKitInformationWidget::autoDetectDebugger); + this, &AndroidGdbServerKitAspectWidget::autoDetectDebugger); QAction *changeAction = buttonMenu->addAction(tr("Edit...")); connect(changeAction, &QAction::triggered, - this, &AndroidGdbServerKitInformationWidget::showDialog); + this, &AndroidGdbServerKitAspectWidget::showDialog); m_button->setMenu(buttonMenu); refresh(); } -AndroidGdbServerKitInformationWidget::~AndroidGdbServerKitInformationWidget() +AndroidGdbServerKitAspectWidget::~AndroidGdbServerKitAspectWidget() { delete m_button; delete m_label; } -QString AndroidGdbServerKitInformationWidget::displayName() const -{ - return tr("Android GDB server"); -} - -QString AndroidGdbServerKitInformationWidget::toolTip() const -{ - return tr("The GDB server to use for this kit."); -} - -void AndroidGdbServerKitInformationWidget::makeReadOnly() +void AndroidGdbServerKitAspectWidget::makeReadOnly() { m_button->setEnabled(false); } -void AndroidGdbServerKitInformationWidget::refresh() -{ - m_label->setText(AndroidGdbServerKitInformation::gdbServer(m_kit).toString()); -} - -bool AndroidGdbServerKitInformationWidget::visibleInKit() +void AndroidGdbServerKitAspectWidget::refresh() { - return DeviceKitInformation::deviceId(m_kit) == Constants::ANDROID_DEVICE_ID; + m_label->setText(AndroidGdbServerKitAspect::gdbServer(m_kit).toString()); } -QWidget *AndroidGdbServerKitInformationWidget::mainWidget() const +QWidget *AndroidGdbServerKitAspectWidget::mainWidget() const { return m_label; } -QWidget *AndroidGdbServerKitInformationWidget::buttonWidget() const +QWidget *AndroidGdbServerKitAspectWidget::buttonWidget() const { return m_button; } -void AndroidGdbServerKitInformationWidget::autoDetectDebugger() +void AndroidGdbServerKitAspectWidget::autoDetectDebugger() { - AndroidGdbServerKitInformation::setGdbSever(m_kit, AndroidGdbServerKitInformation::autoDetect(m_kit)); + AndroidGdbServerKitAspect::setGdbSever(m_kit, AndroidGdbServerKitAspect::autoDetect(m_kit)); } -void AndroidGdbServerKitInformationWidget::showDialog() +void AndroidGdbServerKitAspectWidget::showDialog() { QDialog dialog; auto layout = new QVBoxLayout(&dialog); @@ -194,7 +197,7 @@ void AndroidGdbServerKitInformationWidget::showDialog() auto binaryLabel = new QLabel(tr("&Binary:")); auto chooser = new PathChooser; chooser->setExpectedKind(PathChooser::ExistingCommand); - chooser->setPath(AndroidGdbServerKitInformation::gdbServer(m_kit).toString()); + chooser->setPath(AndroidGdbServerKitAspect::gdbServer(m_kit).toString()); binaryLabel->setBuddy(chooser); formLayout->addRow(binaryLabel, chooser); layout->addLayout(formLayout); @@ -207,7 +210,7 @@ void AndroidGdbServerKitInformationWidget::showDialog() dialog.setWindowTitle(tr("GDB Server for \"%1\"").arg(m_kit->displayName())); if (dialog.exec() == QDialog::Accepted) - AndroidGdbServerKitInformation::setGdbSever(m_kit, chooser->fileName()); + AndroidGdbServerKitAspect::setGdbSever(m_kit, chooser->fileName()); } } // namespace Internal diff --git a/src/plugins/android/androidgdbserverkitinformation.h b/src/plugins/android/androidgdbserverkitinformation.h index 8271926e30..db4f349344 100644 --- a/src/plugins/android/androidgdbserverkitinformation.h +++ b/src/plugins/android/androidgdbserverkitinformation.h @@ -26,60 +26,27 @@ #pragma once #include <projectexplorer/kitinformation.h> -#include <projectexplorer/kitconfigwidget.h> - -QT_BEGIN_NAMESPACE -class QLabel; -class QPushButton; -QT_END_NAMESPACE namespace Android { namespace Internal { -class AndroidGdbServerKitInformationWidget : public ProjectExplorer::KitConfigWidget -{ - Q_OBJECT -public: - AndroidGdbServerKitInformationWidget(ProjectExplorer::Kit *kit, - const ProjectExplorer::KitInformation *ki); - ~AndroidGdbServerKitInformationWidget() override; - - QString displayName() const override; - QString toolTip() const override; - void makeReadOnly() override; - void refresh() override; - bool visibleInKit() override; - - QWidget *mainWidget() const override; - QWidget *buttonWidget() const override; - -private: - void autoDetectDebugger(); - void showDialog(); - - QLabel *m_label; - QPushButton *m_button; -}; - -class AndroidGdbServerKitInformation : public ProjectExplorer::KitInformation +class AndroidGdbServerKitAspect : public ProjectExplorer::KitAspect { Q_OBJECT public: - AndroidGdbServerKitInformation(); - - QVariant defaultValue(const ProjectExplorer::Kit *) const override; - - QList<ProjectExplorer::Task> validate(const ProjectExplorer::Kit *) const override; + AndroidGdbServerKitAspect(); + void setup(ProjectExplorer::Kit *) override; + ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *) const override; + bool isApplicableToKit(const ProjectExplorer::Kit *k) const override; ItemList toUserOutput(const ProjectExplorer::Kit *) const override; - ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *) const override; + ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *) const override; static Core::Id id(); - static bool isAndroidKit(const ProjectExplorer::Kit *kit); - static Utils::FileName gdbServer(const ProjectExplorer::Kit *kit); - static void setGdbSever(ProjectExplorer::Kit *kit, const Utils::FileName &gdbServerCommand); - static Utils::FileName autoDetect(const ProjectExplorer::Kit *kit); + static Utils::FilePath gdbServer(const ProjectExplorer::Kit *kit); + static void setGdbSever(ProjectExplorer::Kit *kit, const Utils::FilePath &gdbServerCommand); + static Utils::FilePath autoDetect(const ProjectExplorer::Kit *kit); }; } // namespace Internal diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index c31302f114..bccc0e3b2a 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -109,7 +109,7 @@ public: using LibrariesMap = QMap<QString, Library>; -static bool openXmlFile(QDomDocument &doc, const Utils::FileName &fileName); +static bool openXmlFile(QDomDocument &doc, const Utils::FilePath &fileName); static bool openManifest(ProjectExplorer::Target *target, QDomDocument &doc); static int parseMinSdk(const QDomElement &manifestElem); @@ -129,7 +129,7 @@ QString AndroidManager::packageName(ProjectExplorer::Target *target) return manifestElem.attribute(QLatin1String("package")); } -QString AndroidManager::packageName(const Utils::FileName &manifestFile) +QString AndroidManager::packageName(const Utils::FilePath &manifestFile) { QDomDocument doc; if (!openXmlFile(doc, manifestFile)) @@ -174,7 +174,7 @@ int AndroidManager::packageVersionCode(const QString &deviceSerial, return -1; } -void AndroidManager::apkInfo(const Utils::FileName &apkPath, +void AndroidManager::apkInfo(const Utils::FilePath &apkPath, QString *packageName, int *version, QString *activityPath) @@ -235,10 +235,10 @@ int AndroidManager::minimumSDK(ProjectExplorer::Target *target) int AndroidManager::minimumSDK(const ProjectExplorer::Kit *kit) { int minSDKVersion = -1; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(kit); if (version && version->targetDeviceTypes().contains(Constants::ANDROID_DEVICE_TYPE)) { - Utils::FileName stockManifestFilePath = - Utils::FileName::fromUserInput(version->qmakeProperty("QT_INSTALL_PREFIX") + + Utils::FilePath stockManifestFilePath = + Utils::FilePath::fromUserInput(version->qmakeProperty("QT_INSTALL_PREFIX") + QLatin1String("/src/android/templates/AndroidManifest.xml")); QDomDocument doc; if (openXmlFile(doc, stockManifestFilePath)) { @@ -248,12 +248,6 @@ int AndroidManager::minimumSDK(const ProjectExplorer::Kit *kit) return minSDKVersion; } -int AndroidManager::minimumNDK(const Kit *kit) -{ - auto qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit)); - return qt->mininmumNDK(); -} - QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target) { if (auto androidBuildApkStep = AndroidBuildApkStep::findInBuild(target->activeBuildConfiguration())) @@ -264,26 +258,54 @@ QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target) return fallback; } -QString AndroidManager::targetArch(ProjectExplorer::Target *target) +QString AndroidManager::targetArch(const Target *target) { - auto qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(target->kit())); + auto qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitAspect::qtVersion(target->kit())); return qt->targetArch(); } -Utils::FileName AndroidManager::dirPath(const ProjectExplorer::Target *target) +QJsonObject AndroidManager::deploymentSettings(const Target *target) +{ + QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit()); + if (!qt) + return {}; + + auto tc = ProjectExplorer::ToolChainKitAspect::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); + if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_ID) + return {}; + QJsonObject settings; + settings["description"] = "This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."; + settings["qt"] = qt->qmakeProperty("QT_INSTALL_PREFIX"); + settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString(); + settings["sdk"] = AndroidConfigurations::currentConfig().sdkLocation().toString(); + settings["sdkBuildToolsRevision"] = AndroidConfigurations::currentConfig().buildToolsVersion().toString(); + settings["application-binary"] = target->activeRunConfiguration()->buildTargetInfo().targetFilePath.toString(); + settings["target-architecture"] = targetArch(target); + settings["toolchain-prefix"] = "llvm"; + settings["tool-prefix"] = "llvm"; + settings["useLLVM"] = true; + settings["ndk-host"] = AndroidConfigurations::currentConfig().toolchainHost(); + settings["stdcpp-path"] = AndroidConfigurations::currentConfig().ndkLocation() + .pathAppended("/sources/cxx-stl/llvm-libc++/libs/" + + targetArch(target) + + "/libc++_shared.so").toString(); + return settings; +} + +Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target) { if (target->activeBuildConfiguration()) - return target->activeBuildConfiguration()->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)); - return Utils::FileName(); + return target->activeBuildConfiguration()->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY); + return Utils::FilePath(); } -Utils::FileName AndroidManager::apkPath(const ProjectExplorer::Target *target) +Utils::FilePath AndroidManager::apkPath(const ProjectExplorer::Target *target) { - QTC_ASSERT(target, return Utils::FileName()); + QTC_ASSERT(target, return Utils::FilePath()); auto buildApkStep = AndroidBuildApkStep::findInBuild(target->activeBuildConfiguration()); if (!buildApkStep) - return Utils::FileName(); + return Utils::FilePath(); QString apkPath("build/outputs/apk/android-build-"); if (buildApkStep->signPackage()) @@ -291,16 +313,16 @@ Utils::FileName AndroidManager::apkPath(const ProjectExplorer::Target *target) else apkPath += QLatin1String("debug.apk"); - return dirPath(target).appendPath(apkPath); + return dirPath(target).pathAppended(apkPath); } -Utils::FileName AndroidManager::manifestSourcePath(ProjectExplorer::Target *target) +Utils::FilePath AndroidManager::manifestSourcePath(ProjectExplorer::Target *target) { if (const ProjectNode *node = currentProjectNode(target)) { const QString packageSource = node->data(Android::Constants::AndroidPackageSourceDir).toString(); if (!packageSource.isEmpty()) { - const FileName manifest = FileName::fromUserInput(packageSource + "/AndroidManifest.xml"); + const FilePath manifest = FilePath::fromUserInput(packageSource + "/AndroidManifest.xml"); if (manifest.exists()) return manifest; } @@ -308,14 +330,22 @@ Utils::FileName AndroidManager::manifestSourcePath(ProjectExplorer::Target *targ return manifestPath(target); } -Utils::FileName AndroidManager::manifestPath(ProjectExplorer::Target *target) +Utils::FilePath AndroidManager::manifestPath(ProjectExplorer::Target *target) +{ + QVariant manifest = target->namedSettings(AndroidManifestName); + if (manifest.isValid()) + return manifest.value<FilePath>(); + return dirPath(target).pathAppended(AndroidManifestName); +} + +void AndroidManager::setManifestPath(Target *target, const FilePath &path) { - return dirPath(target).appendPath(AndroidManifestName); + target->setNamedSettings(AndroidManifestName, QVariant::fromValue(path)); } -Utils::FileName AndroidManager::defaultPropertiesPath(ProjectExplorer::Target *target) +Utils::FilePath AndroidManager::defaultPropertiesPath(ProjectExplorer::Target *target) { - return dirPath(target).appendPath(AndroidDefaultPropertiesName); + return dirPath(target).pathAppended(AndroidDefaultPropertiesName); } QString AndroidManager::deviceSerialNumber(ProjectExplorer::Target *target) @@ -410,7 +440,7 @@ static void raiseError(const QString &reason) QMessageBox::critical(nullptr, AndroidManager::tr("Error creating Android templates."), reason); } -static bool openXmlFile(QDomDocument &doc, const Utils::FileName &fileName) +static bool openXmlFile(QDomDocument &doc, const Utils::FilePath &fileName) { QFile f(fileName.toString()); if (!f.open(QIODevice::ReadOnly)) @@ -603,7 +633,7 @@ static bool mergeGradleProperties(const QString &path, GradleProperties properti bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target) { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit()); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); if (!version) return false; @@ -611,13 +641,14 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target) if (!node) return false; - QFileInfo sourceDirInfo(node->data(Constants::AndroidPackageSourceDir).toString()); - FileName packageSourceDir = FileName::fromString(sourceDirInfo.canonicalFilePath()); - if (!packageSourceDir.appendPath("gradlew").exists()) + const QString sourceDirName = node->data(Constants::AndroidPackageSourceDir).toString(); + QFileInfo sourceDirInfo(sourceDirName); + const FilePath packageSourceDir = FilePath::fromString(sourceDirInfo.canonicalFilePath()) + .pathAppended("gradlew"); + if (!packageSourceDir.exists()) return false; - Utils::FileName wrapperProps = packageSourceDir; - wrapperProps.appendPath(QLatin1String("gradle/wrapper/gradle-wrapper.properties")); + const FilePath wrapperProps = packageSourceDir.pathAppended("gradle/wrapper/gradle-wrapper.properties"); if (wrapperProps.exists()) { GradleProperties wrapperProperties = readGradleProperties(wrapperProps.toString()); QString distributionUrl = QString::fromLocal8Bit(wrapperProperties["distributionUrl"]); @@ -630,10 +661,11 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target) GradleProperties localProperties; localProperties["sdk.dir"] = AndroidConfigurations::currentConfig().sdkLocation().toString().toLocal8Bit(); - if (!mergeGradleProperties(packageSourceDir.appendPath("local.properties").toString(), localProperties)) + const FilePath localPropertiesFile = packageSourceDir.pathAppended("local.properties"); + if (!mergeGradleProperties(localPropertiesFile.toString(), localProperties)) return false; - QString gradlePropertiesPath = packageSourceDir.appendPath("gradle.properties").toString(); + const QString gradlePropertiesPath = packageSourceDir.pathAppended("gradle.properties").toString(); GradleProperties gradleProperties = readGradleProperties(gradlePropertiesPath); gradleProperties["qt5AndroidDir"] = version->qmakeProperty("QT_INSTALL_PREFIX") .append(QLatin1String("/src/android/java")).toLocal8Bit(); @@ -648,11 +680,10 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target) return mergeGradleProperties(gradlePropertiesPath, gradleProperties); } -int AndroidManager::findApiLevel(const Utils::FileName &platformPath) +int AndroidManager::findApiLevel(const Utils::FilePath &platformPath) { int apiLevel = -1; - Utils::FileName propertiesPath = platformPath; - propertiesPath.appendPath("/source.properties"); + const Utils::FilePath propertiesPath = platformPath.pathAppended("/source.properties"); if (propertiesPath.exists()) { QSettings sdkProperties(propertiesPath.toString(), QSettings::IniFormat); bool validInt = false; @@ -672,7 +703,7 @@ QProcess *AndroidManager::runAdbCommandDetached(const QStringList &args, QString p->start(adb, args); if (p->waitForStarted(500) && p->state() == QProcess::Running) { if (deleteOnFinish) { - connect(p.get(), static_cast<void (QProcess::*)(int)>(&QProcess::finished), + connect(p.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), p.get(), &QObject::deleteLater); } return p.release(); diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index e624f2dd1d..12bf9ddf90 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -40,7 +40,7 @@ class Kit; class Target; } -namespace Utils { class FileName; } +namespace Utils { class FilePath; } namespace Android { @@ -66,10 +66,10 @@ class ANDROID_EXPORT AndroidManager : public QObject public: static QString packageName(ProjectExplorer::Target *target); - static QString packageName(const Utils::FileName &manifestFile); + static QString packageName(const Utils::FilePath &manifestFile); static bool packageInstalled(const QString &deviceSerial, const QString &packageName); static int packageVersionCode(const QString &deviceSerial, const QString &packageName); - static void apkInfo(const Utils::FileName &apkPath, + static void apkInfo(const Utils::FilePath &apkPath, QString *packageName = nullptr, int *version = nullptr, QString *activityPath = nullptr); @@ -86,15 +86,15 @@ public: static int minimumSDK(ProjectExplorer::Target *target); static int minimumSDK(const ProjectExplorer::Kit *kit); - static int minimumNDK(const ProjectExplorer::Kit *kit); - static QString targetArch(ProjectExplorer::Target *target); + static QString targetArch(const ProjectExplorer::Target *target); - static Utils::FileName dirPath(const ProjectExplorer::Target *target); - static Utils::FileName manifestPath(ProjectExplorer::Target *target); - static Utils::FileName manifestSourcePath(ProjectExplorer::Target *target); - static Utils::FileName defaultPropertiesPath(ProjectExplorer::Target *target); - static Utils::FileName apkPath(const ProjectExplorer::Target *target); + static Utils::FilePath dirPath(const ProjectExplorer::Target *target); + static Utils::FilePath manifestPath(ProjectExplorer::Target *target); + static void setManifestPath(ProjectExplorer::Target *target, const Utils::FilePath &path); + static Utils::FilePath manifestSourcePath(ProjectExplorer::Target *target); + static Utils::FilePath defaultPropertiesPath(ProjectExplorer::Target *target); + static Utils::FilePath apkPath(const ProjectExplorer::Target *target); static QPair<int, int> apiLevelRange(); static QString androidNameForApiLevel(int x); @@ -107,7 +107,7 @@ public: static bool checkCertificateExists(const QString &keystorePath, const QString &keystorePasswd, const QString &alias); static bool updateGradleProperties(ProjectExplorer::Target *target); - static int findApiLevel(const Utils::FileName &platformPath); + static int findApiLevel(const Utils::FilePath &platformPath); static QProcess *runAdbCommandDetached(const QStringList &args, QString *err = nullptr, bool deleteOnFinish = false); @@ -115,6 +115,8 @@ public: int timeoutS = 30); static SdkToolResult runAaptCommand(const QStringList &args, int timeoutS = 30); + static QJsonObject deploymentSettings(const ProjectExplorer::Target *target); + private: static SdkToolResult runCommand(const QString &executable, const QStringList &args, const QByteArray &writeData = {}, int timeoutS = 30); diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index e040c0db87..72ab0c9984 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -85,13 +85,13 @@ bool checkPackageName(const QString &packageName) return QRegExp(packageNameRegExp).exactMatch(packageName); } -Project *androidProject(const Utils::FileName &fileName) +Project *androidProject(const Utils::FilePath &fileName) { for (Project *project : SessionManager::projects()) { if (!project->activeTarget()) continue; Kit *kit = project->activeTarget()->kit(); - if (DeviceTypeKitInformation::deviceTypeId(kit) == Android::Constants::ANDROID_DEVICE_TYPE + if (DeviceTypeKitAspect::deviceTypeId(kit) == Android::Constants::ANDROID_DEVICE_TYPE && fileName.isChildOf(project->projectDirectory())) return project; } @@ -202,10 +202,10 @@ void AndroidManifestEditorWidget::initializePage() connect(m_versionNameLinedit, &QLineEdit::textEdited, this, setDirtyFunc); connect(m_androidMinSdkVersion, - static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + QOverload<int>::of(&QComboBox::currentIndexChanged), this, setDirtyFunc); connect(m_androidTargetSdkVersion, - static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + QOverload<int>::of(&QComboBox::currentIndexChanged), this, setDirtyFunc); } @@ -492,7 +492,7 @@ void AndroidManifestEditorWidget::updateTargetComboBox() QStringList items; if (project) { Kit *kit = project->activeTarget()->kit(); - if (DeviceTypeKitInformation::deviceTypeId(kit) == Constants::ANDROID_DEVICE_TYPE) { + if (DeviceTypeKitAspect::deviceTypeId(kit) == Constants::ANDROID_DEVICE_TYPE) { ProjectNode *root = project->rootProjectNode(); root->forEachProjectNode([&items](const ProjectNode *projectNode) { items << projectNode->targetApplications(); @@ -604,7 +604,7 @@ void AndroidManifestEditorWidget::preSave() void AndroidManifestEditorWidget::postSave() { - const Utils::FileName docPath = m_textEditorWidget->textDocument()->filePath(); + const Utils::FilePath docPath = m_textEditorWidget->textDocument()->filePath(); ProjectExplorer::Project *project = androidProject(docPath); if (project) { if (Target *target = project->activeTarget()) { @@ -1211,23 +1211,17 @@ void AndroidManifestEditorWidget::parseUnknownElement(QXmlStreamReader &reader, } } -QString AndroidManifestEditorWidget::iconPath(const QString &baseDir, IconDPI dpi) +QString AndroidManifestEditorWidget::iconPath(IconDPI dpi) { - Utils::FileName fileName = Utils::FileName::fromString(baseDir); switch (dpi) { case HighDPI: - fileName.appendPath(QLatin1String("res/drawable-hdpi/icon.png")); - break; + return QString("/res/drawable-hdpi/icon.png"); case MediumDPI: - fileName.appendPath(QLatin1String("res/drawable-mdpi/icon.png")); - break; + return QString("/res/drawable-mdpi/icon.png"); case LowDPI: - fileName.appendPath(QLatin1String("res/drawable-ldpi/icon.png")); - break; - default: - return QString(); + return QString("/res/drawable-ldpi/icon.png"); } - return fileName.toString(); + return {}; } QIcon AndroidManifestEditorWidget::icon(const QString &baseDir, IconDPI dpi) @@ -1242,7 +1236,7 @@ QIcon AndroidManifestEditorWidget::icon(const QString &baseDir, IconDPI dpi) if (dpi == LowDPI && !m_lIconPath.isEmpty()) return QIcon(m_lIconPath); - QString fileName = iconPath(baseDir, dpi); + QString fileName = baseDir + iconPath(dpi); if (fileName.isEmpty()) return QIcon(); return QIcon(fileName); @@ -1253,7 +1247,7 @@ void AndroidManifestEditorWidget::copyIcon(IconDPI dpi, const QString &baseDir, if (!QFileInfo::exists(filePath)) return; - const QString targetPath = iconPath(baseDir, dpi); + const QString targetPath = baseDir + iconPath(dpi); QFile::remove(targetPath); QDir dir; dir.mkpath(QFileInfo(targetPath).absolutePath()); diff --git a/src/plugins/android/androidmanifesteditorwidget.h b/src/plugins/android/androidmanifesteditorwidget.h index 49d1ec1155..d7a7ff092c 100644 --- a/src/plugins/android/androidmanifesteditorwidget.h +++ b/src/plugins/android/androidmanifesteditorwidget.h @@ -137,7 +137,7 @@ private: int *errorLine, int *errorColumn); enum IconDPI { LowDPI, MediumDPI, HighDPI }; QIcon icon(const QString &baseDir, IconDPI dpi); - QString iconPath(const QString &baseDir, IconDPI dpi); + QString iconPath(IconDPI dpi); void copyIcon(IconDPI dpi, const QString &baseDir, const QString &filePath); void updateInfoBar(const QString &errorMessage, int line, int column); diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index a5d81c2f87..9ad698bdec 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -61,17 +61,18 @@ AndroidPackageInstallationStep::AndroidPackageInstallationStep(BuildStepList *bs bool AndroidPackageInstallationStep::init() { BuildConfiguration *bc = buildConfiguration(); - QString dirPath = bc->buildDirectory().appendPath(Constants::ANDROID_BUILDDIRECTORY).toString(); + QString dirPath = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString(); if (HostOsInfo::isWindowsHost()) if (bc->environment().searchInPath("sh.exe").isEmpty()) dirPath = QDir::toNativeSeparators(dirPath); - ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit(), + ToolChain *tc = ToolChainKitAspect::toolChain(target()->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); + QTC_ASSERT(tc, return false); ProcessParameters *pp = processParameters(); pp->setMacroExpander(bc->macroExpander()); - pp->setWorkingDirectory(bc->buildDirectory().toString()); + pp->setWorkingDirectory(bc->buildDirectory()); pp->setCommand(tc->makeCommand(bc->environment())); Environment env = bc->environment(); Environment::setupEnglishOutput(&env); @@ -99,7 +100,7 @@ void AndroidPackageInstallationStep::doRun() { QString error; foreach (const QString &dir, m_androidDirsToClean) { - FileName androidDir = FileName::fromString(dir); + FilePath androidDir = FilePath::fromString(dir); if (!dir.isEmpty() && androidDir.exists()) { emit addOutput(tr("Removing directory %1").arg(dir), OutputFormat::NormalMessage); if (!FileUtils::removeRecursively(androidDir, &error)) { diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 2b19da438f..29f4392712 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -30,14 +30,13 @@ #include "androiddebugsupport.h" #include "androiddeployqtstep.h" #include "androiddevice.h" -#include "androiddevicefactory.h" #include "androidgdbserverkitinformation.h" #include "androidmanager.h" #include "androidmanifesteditorfactory.h" #include "androidpackageinstallationstep.h" #include "androidpotentialkit.h" #include "androidqmltoolingsupport.h" -#include "androidqtversionfactory.h" +#include "androidqtversion.h" #include "androidrunconfiguration.h" #include "androidruncontrol.h" #include "androidsettingspage.h" @@ -86,10 +85,25 @@ public: registerRunConfiguration<Android::AndroidRunConfiguration> ("Qt4ProjectManager.AndroidRunConfiguration:"); addSupportedTargetDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); - addRunWorkerFactory<AndroidRunSupport>(NORMAL_RUN_MODE); - addRunWorkerFactory<AndroidDebugSupport>(DEBUG_RUN_MODE); - addRunWorkerFactory<AndroidQmlToolingSupport>(QML_PROFILER_RUN_MODE); - addRunWorkerFactory<AndroidQmlToolingSupport>(QML_PREVIEW_RUN_MODE); + } +}; + +class QmlPreviewRunWorkerFactory : public RunWorkerFactory +{ +public: + QmlPreviewRunWorkerFactory() + { + addSupportedRunMode(QML_PREVIEW_RUN_MODE); + setProducer([](RunControl *runControl) -> RunWorker * { + const Runnable runnable = runControl->runConfiguration()->runnable(); + return new AndroidQmlToolingSupport(runControl, runnable.executable); + }); + addConstraint([](RunConfiguration *runConfig) { + return runConfig->isEnabled() + && runConfig->id().name().startsWith("QmlProjectManager.QmlRunConfiguration") + && DeviceTypeKitAspect::deviceTypeId(runConfig->target()->kit()) + == Android::Constants::ANDROID_DEVICE_TYPE; + }); } }; @@ -107,7 +121,7 @@ public: void handleNewTarget(Target *target) { - if (DeviceTypeKitInformation::deviceTypeId(target->kit()) != Android::Constants::ANDROID_DEVICE_TYPE) + if (DeviceTypeKitAspect::deviceTypeId(target->kit()) != Android::Constants::ANDROID_DEVICE_TYPE) return; for (BuildConfiguration *bc : target->buildConfigurations()) @@ -136,7 +150,18 @@ public: AndroidPackageInstallationFactory packackeInstallationFactory; AndroidManifestEditorFactory manifestEditorFactory; AndroidRunConfigurationFactory runConfigFactory; + + SimpleRunWorkerFactory<AndroidRunSupport, AndroidRunConfiguration> runWorkerFactory; + SimpleRunWorkerFactory<AndroidDebugSupport, AndroidRunConfiguration> + debugWorkerFactory{DEBUG_RUN_MODE}; + SimpleRunWorkerFactory<AndroidQmlToolingSupport, AndroidRunConfiguration> + profilerWorkerFactory{QML_PROFILER_RUN_MODE}; + SimpleRunWorkerFactory<AndroidQmlToolingSupport, AndroidRunConfiguration> + qmlPreviewWorkerFactory{QML_PREVIEW_RUN_MODE}; + QmlPreviewRunWorkerFactory qmlPreviewWorkerFactory2; + AndroidBuildApkStepFactory buildApkStepFactory; + AndroidGdbServerKitAspect gdbServerKitAspect; }; AndroidPlugin::~AndroidPlugin() @@ -149,20 +174,8 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa Q_UNUSED(arguments); Q_UNUSED(errorMessage); - RunControl::registerWorker(QML_PREVIEW_RUN_MODE, [](RunControl *runControl) -> RunWorker* { - const Runnable runnable = runControl->runConfiguration()->runnable(); - return new AndroidQmlToolingSupport(runControl, runnable.executable); - }, [](RunConfiguration *runConfig) { - return runConfig->isEnabled() - && runConfig->id().name().startsWith("QmlProjectManager.QmlRunConfiguration") - && DeviceTypeKitInformation::deviceTypeId(runConfig->target()->kit()) - == Android::Constants::ANDROID_DEVICE_TYPE; - }); - d = new AndroidPluginPrivate; - KitManager::registerKitInformation<Internal::AndroidGdbServerKitInformation>(); - connect(KitManager::instance(), &KitManager::kitsLoaded, this, &AndroidPlugin::kitsRestored); diff --git a/src/plugins/android/androidplugin.h b/src/plugins/android/androidplugin.h index 5f71e3886c..7042491b86 100644 --- a/src/plugins/android/androidplugin.h +++ b/src/plugins/android/androidplugin.h @@ -29,16 +29,12 @@ namespace Android { namespace Internal { -class AndroidPluginPrivate; + class AndroidPlugin : public ExtensionSystem::IPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Android.json") -public: - AndroidPlugin() = default; - -private: ~AndroidPlugin() final; bool initialize(const QStringList &arguments, QString *errorMessage) final; @@ -46,7 +42,7 @@ private: void kitsRestored(); - AndroidPluginPrivate *d = nullptr; + class AndroidPluginPrivate *d = nullptr; }; } // namespace Internal diff --git a/src/plugins/android/androidpotentialkit.cpp b/src/plugins/android/androidpotentialkit.cpp index 8264415a12..f755551b28 100644 --- a/src/plugins/android/androidpotentialkit.cpp +++ b/src/plugins/android/androidpotentialkit.cpp @@ -68,7 +68,7 @@ bool AndroidPotentialKit::isEnabled() const { QList<ProjectExplorer::Kit *> kits = ProjectExplorer::KitManager::kits(); foreach (ProjectExplorer::Kit *kit, kits) { - Core::Id deviceId = ProjectExplorer::DeviceKitInformation::deviceId(kit); + Core::Id deviceId = ProjectExplorer::DeviceKitAspect::deviceId(kit); if (kit->isAutoDetected() && deviceId == Core::Id(Constants::ANDROID_DEVICE_ID) && !kit->isSdkProvided()) { @@ -120,7 +120,7 @@ void AndroidPotentialKitWidget::recheck() { QList<ProjectExplorer::Kit *> kits = ProjectExplorer::KitManager::kits(); foreach (ProjectExplorer::Kit *kit, kits) { - Core::Id deviceId = ProjectExplorer::DeviceKitInformation::deviceId(kit); + Core::Id deviceId = ProjectExplorer::DeviceKitAspect::deviceId(kit); if (kit->isAutoDetected() && deviceId == Core::Id(Constants::ANDROID_DEVICE_ID) && !kit->isSdkProvided()) { diff --git a/src/plugins/android/androidqmltoolingsupport.h b/src/plugins/android/androidqmltoolingsupport.h index 5e1d00aa3b..8351de59a9 100644 --- a/src/plugins/android/androidqmltoolingsupport.h +++ b/src/plugins/android/androidqmltoolingsupport.h @@ -25,7 +25,7 @@ #pragma once -#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/runcontrol.h> #include <utils/environment.h> namespace Android { diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index 9916fc1deb..eff95c3f04 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -42,30 +42,16 @@ #include <proparser/profileevaluator.h> -using namespace Android::Internal; using namespace ProjectExplorer; +namespace Android { +namespace Internal { + AndroidQtVersion::AndroidQtVersion() : QtSupport::BaseQtVersion() { } -AndroidQtVersion::AndroidQtVersion(const Utils::FileName &path, bool isAutodetected, const QString &autodetectionSource) - : QtSupport::BaseQtVersion(path, isAutodetected, autodetectionSource) -{ - setUnexpandedDisplayName(defaultUnexpandedDisplayName(path, false)); -} - -AndroidQtVersion *AndroidQtVersion::clone() const -{ - return new AndroidQtVersion(*this); -} - -QString AndroidQtVersion::type() const -{ - return QLatin1String(Constants::ANDROIDQT); -} - bool AndroidQtVersion::isValid() const { if (!BaseQtVersion::isValid()) @@ -83,9 +69,9 @@ QString AndroidQtVersion::invalidReason() const return tmp; } -QList<Abi> AndroidQtVersion::detectQtAbis() const +Abis AndroidQtVersion::detectQtAbis() const { - QList<Abi> abis = qtAbisFromLibrary(qtCorePaths()); + Abis abis = BaseQtVersion::detectQtAbis(); for (int i = 0; i < abis.count(); ++i) { abis[i] = Abi(abis.at(i).architecture(), abis.at(i).os(), @@ -103,7 +89,7 @@ void AndroidQtVersion::addToEnvironment(const Kit *k, Utils::Environment &env) c env.set(QLatin1String("ANDROID_NDK_HOST"), config.toolchainHost()); env.set(QLatin1String("ANDROID_NDK_ROOT"), config.ndkLocation().toUserOutput()); env.set(QLatin1String("ANDROID_NDK_PLATFORM"), - config.bestNdkPlatformMatch(qMax(AndroidManager::minimumNDK(k), AndroidManager::minimumSDK(k)))); + config.bestNdkPlatformMatch(qMax(minimumNDK(), AndroidManager::minimumSDK(k)))); } Utils::Environment AndroidQtVersion::qmakeRunEnvironment() const @@ -125,7 +111,7 @@ QString AndroidQtVersion::targetArch() const return m_targetArch; } -int AndroidQtVersion::mininmumNDK() const +int AndroidQtVersion::minimumNDK() const { ensureMkSpecParsed(); return m_minNdk; @@ -160,3 +146,22 @@ QSet<Core::Id> AndroidQtVersion::targetDeviceTypes() const { return {Constants::ANDROID_DEVICE_TYPE}; } + + +// Factory + +AndroidQtVersionFactory::AndroidQtVersionFactory() +{ + setQtVersionCreator([] { return new AndroidQtVersion; }); + setSupportedType(Constants::ANDROIDQT); + setPriority(90); + + setRestrictionChecker([](const SetupData &setup) { + return !setup.config.contains("android-no-sdk") + && (setup.config.contains("android") + || setup.platforms.contains("android")); + }); +} + +} // Internal +} // Android diff --git a/src/plugins/android/androidqtversion.h b/src/plugins/android/androidqtversion.h index d009c68ceb..519d702ead 100644 --- a/src/plugins/android/androidqtversion.h +++ b/src/plugins/android/androidqtversion.h @@ -26,6 +26,7 @@ #pragma once #include <qtsupport/baseqtversion.h> +#include <qtsupport/qtversionfactory.h> #include <QCoreApplication> @@ -38,14 +39,11 @@ class AndroidQtVersion : public QtSupport::BaseQtVersion public: AndroidQtVersion(); - AndroidQtVersion(const Utils::FileName &path, bool isAutodetected = false, const QString &autodetectionSource = QString()); - AndroidQtVersion *clone() const override; - QString type() const override; bool isValid() const override; QString invalidReason() const override; - QList<ProjectExplorer::Abi> detectQtAbis() const override; + ProjectExplorer::Abis detectQtAbis() const override; void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const override; Utils::Environment qmakeRunEnvironment() const override; @@ -55,7 +53,8 @@ public: QString description() const override; QString targetArch() const; - int mininmumNDK() const; + int minimumNDK() const; + protected: void parseMkSpec(ProFileEvaluator *) const override; private: @@ -63,5 +62,11 @@ private: mutable int m_minNdk = -1; }; +class AndroidQtVersionFactory : public QtSupport::QtVersionFactory +{ +public: + AndroidQtVersionFactory(); +}; + } // namespace Internal } // namespace Android diff --git a/src/plugins/android/androidqtversionfactory.cpp b/src/plugins/android/androidqtversionfactory.cpp deleted file mode 100644 index 00df010def..0000000000 --- a/src/plugins/android/androidqtversionfactory.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "androidqtversionfactory.h" -#include "androidqtversion.h" -#include "androidconstants.h" -#include <qtsupport/qtsupportconstants.h> -#include <utils/qtcassert.h> -#include <proparser/profileevaluator.h> - -#include <QFileInfo> - -namespace Android { -namespace Internal { - -AndroidQtVersionFactory::AndroidQtVersionFactory(QObject *parent) - : QtSupport::QtVersionFactory(parent) -{ -} - -bool AndroidQtVersionFactory::canRestore(const QString &type) -{ - return type == QLatin1String(Constants::ANDROIDQT); -} - -QtSupport::BaseQtVersion *AndroidQtVersionFactory::restore(const QString &type, - const QVariantMap &data) -{ - QTC_ASSERT(canRestore(type), return nullptr); - auto v = new AndroidQtVersion; - v->fromMap(data); - return v; -} - -int AndroidQtVersionFactory::priority() const -{ - return 90; -} - -QtSupport::BaseQtVersion *AndroidQtVersionFactory::create(const Utils::FileName &qmakePath, ProFileEvaluator *evaluator, bool isAutoDetected, const QString &autoDetectionSource) -{ - QFileInfo fi = qmakePath.toFileInfo(); - if (!fi.exists() || !fi.isExecutable() || !fi.isFile()) - return nullptr; - if (!evaluator->values(QLatin1String("CONFIG")).contains(QLatin1String("android")) - && evaluator->value(QLatin1String("QMAKE_PLATFORM")) != QLatin1String("android")) - return nullptr; - if (evaluator->values(QLatin1String("CONFIG")).contains(QLatin1String("android-no-sdk"))) - return nullptr; - return new AndroidQtVersion(qmakePath, isAutoDetected, autoDetectionSource); -} - -} // Internal -} // Android diff --git a/src/plugins/android/androidqtversionfactory.h b/src/plugins/android/androidqtversionfactory.h deleted file mode 100644 index 92d2e44725..0000000000 --- a/src/plugins/android/androidqtversionfactory.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <qtsupport/qtversionfactory.h> - -namespace Android { -namespace Internal { - -class AndroidQtVersionFactory : public QtSupport::QtVersionFactory -{ -public: - explicit AndroidQtVersionFactory(QObject *parent = nullptr); - - bool canRestore(const QString &type) override; - QtSupport::BaseQtVersion *restore(const QString &type, const QVariantMap &data) override; - - int priority() const override; - QtSupport::BaseQtVersion *create(const Utils::FileName &qmakePath, ProFileEvaluator *evaluator, - bool isAutoDetected = false, const QString &autoDetectionSource = QString()) override; -}; - -} // namespace Internal -} // namespace Android diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp index 1f16851fff..fa81749cd4 100644 --- a/src/plugins/android/androidrunconfiguration.cpp +++ b/src/plugins/android/androidrunconfiguration.cpp @@ -30,7 +30,6 @@ #include "androidtoolchain.h" #include "androidmanager.h" #include "adbcommandswidget.h" -#include "androidrunenvironmentaspect.h" #include <projectexplorer/kitinformation.h> #include <projectexplorer/project.h> @@ -108,7 +107,9 @@ void BaseStringListAspect::setLabel(const QString &label) AndroidRunConfiguration::AndroidRunConfiguration(Target *target, Core::Id id) : RunConfiguration(target, id) { - addAspect<AndroidRunEnvironmentAspect>(); + auto envAspect = addAspect<EnvironmentAspect>(); + envAspect->addSupportedBaseEnvironment(tr("Clean Environment"), {}); + addAspect<ArgumentsAspect>(); auto amStartArgsAspect = addAspect<BaseStringAspect>(); @@ -155,22 +156,4 @@ void AndroidRunConfiguration::updateTargetInformation() setDefaultDisplayName(bti.displayName); } -QString AndroidRunConfiguration::disabledReason() const -{ - const BuildTargetInfo bti = buildTargetInfo(); - const QString projectFileName = bti.projectFilePath.toString(); - - if (project()->isParsing()) - return tr("The project file \"%1\" is currently being parsed.").arg(projectFileName); - - if (!project()->hasParsingData()) { - if (!bti.projectFilePath.exists()) - return tr("The project file \"%1\" does not exist.").arg(projectFileName); - - return tr("The project file \"%1\" could not be parsed.").arg(projectFileName); - } - - return QString(); -} - } // namespace Android diff --git a/src/plugins/android/androidrunconfiguration.h b/src/plugins/android/androidrunconfiguration.h index bc6e10b90c..6723048f37 100644 --- a/src/plugins/android/androidrunconfiguration.h +++ b/src/plugins/android/androidrunconfiguration.h @@ -68,7 +68,6 @@ class ANDROID_EXPORT AndroidRunConfiguration : public ProjectExplorer::RunConfig public: explicit AndroidRunConfiguration(ProjectExplorer::Target *target, Core::Id id); - QString disabledReason() const override; QWidget *createConfigurationWidget() override; private: diff --git a/src/plugins/android/androidrunenvironmentaspect.cpp b/src/plugins/android/androidrunenvironmentaspect.cpp deleted file mode 100644 index 1db75f0352..0000000000 --- a/src/plugins/android/androidrunenvironmentaspect.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ -#include "androidrunenvironmentaspect.h" - -namespace { -enum BaseEnvironmentBase { - CleanEnvironmentBase -}; -} - -namespace Android { - -AndroidRunEnvironmentAspect::AndroidRunEnvironmentAspect() -{ - addSupportedBaseEnvironment(CleanEnvironmentBase, tr("Clean Environment")); -} - -Utils::Environment AndroidRunEnvironmentAspect::baseEnvironment() const -{ - // Clean Environment - return Utils::Environment(); -} - -} // namespace Android - diff --git a/src/plugins/android/androidrunenvironmentaspect.h b/src/plugins/android/androidrunenvironmentaspect.h deleted file mode 100644 index 0620f57746..0000000000 --- a/src/plugins/android/androidrunenvironmentaspect.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ -#pragma once - -#include <projectexplorer/environmentaspect.h> - -namespace Android { - -class AndroidRunEnvironmentAspect : public ProjectExplorer::EnvironmentAspect -{ - Q_OBJECT - -public: - AndroidRunEnvironmentAspect(); - - Utils::Environment baseEnvironment() const override; -}; - -} // namespace Android - diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index f20f834c60..24ac13a4f1 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -119,7 +119,7 @@ namespace Android { namespace Internal { AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName) - : RunWorker(runControl), m_target(runControl->runConfiguration()->target()) + : RunWorker(runControl), m_target(runControl->target()) { setId("AndroidRunner"); static const int metaTypes[] = { diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h index d56b59c001..d8e0726c1b 100644 --- a/src/plugins/android/androidrunner.h +++ b/src/plugins/android/androidrunner.h @@ -27,7 +27,7 @@ #include "androidconfigurations.h" -#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/runcontrol.h> #include <qmldebug/qmldebugcommandlinearguments.h> #include <qmldebug/qmloutputparser.h> diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index 4a4386740b..b84ec9df74 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -32,11 +32,15 @@ #include "androidgdbserverkitinformation.h" #include <debugger/debuggerrunconfigurationaspect.h> + #include <projectexplorer/environmentaspect.h> #include <projectexplorer/runconfigurationaspects.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/target.h> + #include <qtsupport/baseqtversion.h> #include <qtsupport/qtkitinformation.h> + #include <utils/hostosinfo.h> #include <utils/runextensions.h> #include <utils/synchronousprocess.h> @@ -63,7 +67,6 @@ using namespace ProjectExplorer; namespace Android { namespace Internal { - static const QString pidScript = "pidof -s \"%1\""; static const QString pidScriptPreNougat = QStringLiteral("for p in /proc/[0-9]*; " "do cat <$p/cmdline && echo :${p##*/}; done"); @@ -162,9 +165,9 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa , m_jdbProcess(nullptr, deleter) { - auto runConfig = runner->runControl()->runConfiguration(); - auto aspect = runConfig->aspect<Debugger::DebuggerRunConfigurationAspect>(); - Core::Id runMode = runner->runMode(); + auto runControl = runner->runControl(); + auto aspect = runControl->aspect<Debugger::DebuggerRunConfigurationAspect>(); + Core::Id runMode = runControl->runMode(); const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE; m_useCppDebugger = debuggingMode && aspect->useCppDebugger(); if (debuggingMode && aspect->useQmlDebugger()) @@ -190,27 +193,27 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa m_localJdbServerPort = Utils::Port(5038); QTC_CHECK(m_localJdbServerPort.isValid()); - auto target = runConfig->target(); + auto target = runControl->target(); m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target); m_apiLevel = AndroidManager::deviceApiLevel(target); - m_extraEnvVars = runConfig->aspect<EnvironmentAspect>()->environment(); + m_extraEnvVars = runControl->aspect<EnvironmentAspect>()->environment(); qCDebug(androidRunWorkerLog) << "Environment variables for the app" << m_extraEnvVars.toStringList(); - m_extraAppParams = runConfig->runnable().commandLineArguments; + m_extraAppParams = runControl->runnable().commandLineArguments; - if (auto aspect = runConfig->aspect(Constants::ANDROID_AMSTARTARGS)) + if (auto aspect = runControl->aspect(Constants::ANDROID_AMSTARTARGS)) m_amStartExtraArgs = static_cast<BaseStringAspect *>(aspect)->value().split(' '); - if (auto aspect = runConfig->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) { + if (auto aspect = runControl->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) { for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value()) m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); } for (const QString &shellCmd : runner->recordedData(Constants::ANDROID_PRESTARTSHELLCMDLIST).toStringList()) m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); - if (auto aspect = runConfig->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) { + if (auto aspect = runControl->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) { for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value()) m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd)); } @@ -222,8 +225,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa << "Extra Start Args:" << m_amStartExtraArgs << "Before Start ADB cmds:" << m_beforeStartAdbCommands << "After finish ADB cmds:" << m_afterFinishAdbCommands; - m_gdbserverPath = AndroidGdbServerKitInformation::gdbServer(target->kit()).toString(); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit()); + m_gdbserverPath = AndroidGdbServerKitAspect::gdbServer(target->kit()).toString(); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); m_useAppParamsForQmlDebugger = version->qtVersion() >= QtSupport::QtVersionNumber(5, 12); } @@ -585,11 +588,11 @@ void AndroidRunnerWorker::handleJdbWaiting() } m_afterFinishAdbCommands.push_back(removeForward.join(' ')); - auto jdbPath = AndroidConfigurations::currentConfig().openJDKLocation().appendPath("bin"); + auto jdbPath = AndroidConfigurations::currentConfig().openJDKLocation().pathAppended("bin"); if (Utils::HostOsInfo::isWindowsHost()) - jdbPath.appendPath("jdb.exe"); + jdbPath = jdbPath.pathAppended("jdb.exe"); else - jdbPath.appendPath("jdb"); + jdbPath = jdbPath.pathAppended("jdb"); QStringList jdbArgs("-connect"); jdbArgs << QString("com.sun.jdi.SocketAttach:hostname=localhost,port=%1") @@ -672,7 +675,7 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid) QTC_ASSERT(m_psIsAlive, return); m_psIsAlive->setObjectName("IsAliveProcess"); m_psIsAlive->setProcessChannelMode(QProcess::MergedChannels); - connect(m_psIsAlive.get(), static_cast<void(QProcess::*)(int)>(&QProcess::finished), + connect(m_psIsAlive.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, bind(&AndroidRunnerWorker::onProcessIdChanged, this, -1)); } } diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp index e2c0453d6c..8b58cdd1ad 100644 --- a/src/plugins/android/androidsdkmanager.cpp +++ b/src/plugins/android/androidsdkmanager.cpp @@ -223,7 +223,7 @@ private: AndroidSdkManager &m_sdkManager; const AndroidConfig &m_config; AndroidSdkPackageList m_allPackages; - FileName lastSdkManagerPath; + FilePath lastSdkManagerPath; QString m_licenseTextCache; QByteArray m_licenseUserInput; mutable QReadWriteLock m_licenseInputLock; @@ -243,7 +243,7 @@ class SdkManagerOutputParser QStringList headerParts; QVersionNumber revision; QString description; - Utils::FileName installedLocation; + Utils::FilePath installedLocation; QMap<QString, QString> extraData; }; @@ -612,7 +612,7 @@ bool SdkManagerOutputParser::parseAbstractData(SdkManagerOutputParser::GenericPa for (const auto &key: qAsConst(extraKeys)) { if (valueForKey(key, line, &value)) { if (key == installLocationKey) - output.installedLocation = Utils::FileName::fromString(value); + output.installedLocation = Utils::FilePath::fromString(value); else if (key == revisionKey) output.revision = QVersionNumber::fromString(value); else if (key == descriptionKey) @@ -930,7 +930,7 @@ void AndroidSdkManagerPrivate::getPendingLicense(SdkCmdFutureInterface &fi) QtcProcess licenseCommand; licenseCommand.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(m_config)); bool reviewingLicenses = false; - licenseCommand.setCommand(m_config.sdkManagerToolPath().toString(), {"--licenses"}); + licenseCommand.setCommand(CommandLine(m_config.sdkManagerToolPath(), "--licenses")); if (Utils::HostOsInfo::isWindowsHost()) licenseCommand.setUseCtrlCStub(true); licenseCommand.start(); diff --git a/src/plugins/android/androidsdkpackage.cpp b/src/plugins/android/androidsdkpackage.cpp index 127aa97a2e..59978b3b7d 100644 --- a/src/plugins/android/androidsdkpackage.cpp +++ b/src/plugins/android/androidsdkpackage.cpp @@ -69,7 +69,7 @@ const QString &AndroidSdkPackage::sdkStylePath() const return m_sdkStylePath; } -const Utils::FileName &AndroidSdkPackage::installedLocation() const +const Utils::FilePath &AndroidSdkPackage::installedLocation() const { return m_installedLocation; } @@ -89,7 +89,7 @@ void AndroidSdkPackage::setState(AndroidSdkPackage::PackageState state) m_state = state; } -void AndroidSdkPackage::setInstalledLocation(const Utils::FileName &path) +void AndroidSdkPackage::setInstalledLocation(const Utils::FilePath &path) { m_installedLocation = path; if (m_installedLocation.exists()) diff --git a/src/plugins/android/androidsdkpackage.h b/src/plugins/android/androidsdkpackage.h index beca0472dd..9f85e87be9 100644 --- a/src/plugins/android/androidsdkpackage.h +++ b/src/plugins/android/androidsdkpackage.h @@ -77,13 +77,13 @@ public: const QVersionNumber &revision() const; PackageState state() const; const QString &sdkStylePath() const; - const Utils::FileName &installedLocation() const; + const Utils::FilePath &installedLocation() const; protected: void setDisplayText(const QString &str); void setDescriptionText(const QString &str); void setState(PackageState state); - void setInstalledLocation(const Utils::FileName &path); + void setInstalledLocation(const Utils::FilePath &path); virtual void updatePackageDetails(); @@ -93,7 +93,7 @@ private: QVersionNumber m_revision; PackageState m_state = PackageState::Unknown; QString m_sdkStylePath; - Utils::FileName m_installedLocation; + Utils::FilePath m_installedLocation; friend class Internal::SdkManagerOutputParser; friend class Internal::AndroidToolOutputParser; diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index b45da47d41..494af3065f 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -371,32 +371,28 @@ void AndroidSettingsWidget::saveSettings() void AndroidSettingsWidget::validateJdk() { - auto javaPath = Utils::FileName::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath()); + auto javaPath = Utils::FilePath::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath()); m_androidConfig.setOpenJDKLocation(javaPath); bool jdkPathExists = m_androidConfig.openJDKLocation().exists(); auto summaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget()); summaryWidget->setPointValid(JavaPathExistsRow, jdkPathExists); - Utils::FileName bin = m_androidConfig.openJDKLocation(); - bin.appendPath(QLatin1String("bin/javac" QTC_HOST_EXE_SUFFIX)); + const Utils::FilePath bin = m_androidConfig.openJDKLocation().pathAppended("bin/javac" QTC_HOST_EXE_SUFFIX); summaryWidget->setPointValid(JavaJdkValidRow, jdkPathExists && bin.exists()); updateUI(); } void AndroidSettingsWidget::validateNdk() { - auto ndkPath = Utils::FileName::fromUserInput(m_ui->NDKLocationPathChooser->rawPath()); + auto ndkPath = Utils::FilePath::fromUserInput(m_ui->NDKLocationPathChooser->rawPath()); m_androidConfig.setNdkLocation(ndkPath); auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget()); summaryWidget->setPointValid(NdkPathExistsRow, m_androidConfig.ndkLocation().exists()); - Utils::FileName ndkPlatformsDir(ndkPath); - ndkPlatformsDir.appendPath("platforms"); - Utils::FileName ndkToolChainsDir(ndkPath); - ndkToolChainsDir.appendPath("toolchains"); - Utils::FileName ndkSourcesDir(ndkPath); - ndkSourcesDir.appendPath("sources/cxx-stl"); + const Utils::FilePath ndkPlatformsDir = ndkPath.pathAppended("platforms"); + const Utils::FilePath ndkToolChainsDir = ndkPath.pathAppended("toolchains"); + const Utils::FilePath ndkSourcesDir = ndkPath.pathAppended("sources/cxx-stl"); summaryWidget->setPointValid(NdkDirStructureRow, ndkPlatformsDir.exists() && ndkToolChainsDir.exists() @@ -409,7 +405,7 @@ void AndroidSettingsWidget::validateNdk() void AndroidSettingsWidget::onSdkPathChanged() { - auto sdkPath = Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath()); + auto sdkPath = Utils::FilePath::fromUserInput(m_ui->SDKLocationPathChooser->rawPath()); m_androidConfig.setSdkLocation(sdkPath); // Package reload will trigger validateSdk. m_sdkManager->reloadPackages(); diff --git a/src/plugins/android/androidsignaloperation.cpp b/src/plugins/android/androidsignaloperation.cpp index bb54b833ab..2410ed4732 100644 --- a/src/plugins/android/androidsignaloperation.cpp +++ b/src/plugins/android/androidsignaloperation.cpp @@ -63,8 +63,7 @@ void Android::Internal::AndroidSignalOperation::adbFindRunAsFinished(int exitCod m_state = Idle; emit finished(m_errorMessage); } else { - connect(m_adbProcess, - static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), + connect(m_adbProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &AndroidSignalOperation::adbKillFinished); m_state = Kill; m_timeout->start(); @@ -113,8 +112,7 @@ void Android::Internal::AndroidSignalOperation::signalOperationViaADB(qint64 pid m_adbProcess->disconnect(this); m_pid = pid; m_signal = signal; - connect(m_adbProcess, - static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), + connect(m_adbProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &AndroidSignalOperation::adbFindRunAsFinished); m_state = RunAs; m_timeout->start(); diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index 1a7315309d..3c45885471 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -60,7 +60,7 @@ static const QHash<QString, Abi> ClangTargets = { static const QList<Core::Id> LanguageIds = {ProjectExplorer::Constants::CXX_LANGUAGE_ID, ProjectExplorer::Constants::C_LANGUAGE_ID}; -static ToolChain *findToolChain(Utils::FileName &compilerPath, Core::Id lang, const QString &target, +static ToolChain *findToolChain(Utils::FilePath &compilerPath, Core::Id lang, const QString &target, CToolChainList &alreadyKnown) { ToolChain * tc = Utils::findOrDefault(alreadyKnown, [target, compilerPath, lang](ToolChain *tc) { @@ -92,12 +92,11 @@ void AndroidToolChain::addToEnvironment(Environment &env) const { env.set(QLatin1String("ANDROID_NDK_HOST"), AndroidConfigurations::currentConfig().toolchainHost()); - const Utils::FileName javaHome = AndroidConfigurations::currentConfig().openJDKLocation(); - if (!javaHome.isEmpty() && javaHome.toFileInfo().exists()) { + const Utils::FilePath javaHome = AndroidConfigurations::currentConfig().openJDKLocation(); + if (!javaHome.exists()) { env.set(QLatin1String("JAVA_HOME"), javaHome.toString()); - Utils::FileName javaBin = javaHome; - javaBin.appendPath(QLatin1String("bin")); - if (!Utils::contains(env.path(), [&javaBin](const Utils::FileName &p) { return p == javaBin; })) + const FilePath javaBin = javaHome.pathAppended("bin"); + if (!Utils::contains(env.path(), [&javaBin](const Utils::FilePath &p) { return p == javaBin; })) env.prependOrSetPath(javaBin.toUserOutput()); } env.set(QLatin1String("ANDROID_HOME"), @@ -106,13 +105,13 @@ void AndroidToolChain::addToEnvironment(Environment &env) const AndroidConfigurations::currentConfig().sdkLocation().toString()); } -FileName AndroidToolChain::suggestedDebugger() const +FilePath AndroidToolChain::suggestedDebugger() const { // TODO: Make use of LLDB if available. return AndroidConfigurations::currentConfig().gdbPath(targetAbi()); } -FileName AndroidToolChain::suggestedGdbServer() const +FilePath AndroidToolChain::suggestedGdbServer() const { return AndroidConfigurations::currentConfig().gdbServer(targetAbi()); } @@ -124,17 +123,16 @@ bool AndroidToolChain::fromMap(const QVariantMap &data) return isValid(); } -FileNameList AndroidToolChain::suggestedMkspecList() const +QStringList AndroidToolChain::suggestedMkspecList() const { - return FileNameList() << FileName::fromLatin1("android-g++") - << FileName::fromLatin1("android-clang"); + return {"android-g++", "android-clang"}; } -QString AndroidToolChain::makeCommand(const Environment &env) const +FilePath AndroidToolChain::makeCommand(const Environment &env) const { Q_UNUSED(env); - FileName makePath = AndroidConfigurations::currentConfig().makePath(); - return makePath.exists() ? makePath.toString() : "make"; + FilePath makePath = AndroidConfigurations::currentConfig().makePath(); + return makePath.exists() ? makePath : FilePath::fromString("make"); } GccToolChain::DetectedAbisResult AndroidToolChain::detectSupportedAbis() const @@ -154,11 +152,9 @@ GccToolChain::DetectedAbisResult AndroidToolChain::detectSupportedAbis() const AndroidToolChainFactory::AndroidToolChainFactory() { setDisplayName(tr("Android Clang")); -} - -QSet<Core::Id> Android::Internal::AndroidToolChainFactory::supportedLanguages() const -{ - return {ProjectExplorer::Constants::CXX_LANGUAGE_ID}; + setSupportedToolChainType(Constants::ANDROID_TOOLCHAIN_ID); + setSupportedLanguages({ProjectExplorer::Constants::CXX_LANGUAGE_ID}); + setToolchainConstructor([] { return new AndroidToolChain; }); } ToolChainList AndroidToolChainFactory::autoDetect(CToolChainList &alreadyKnown) @@ -166,24 +162,9 @@ ToolChainList AndroidToolChainFactory::autoDetect(CToolChainList &alreadyKnown) return autodetectToolChainsForNdk(alreadyKnown); } -bool AndroidToolChainFactory::canRestore(const QVariantMap &data) +static FilePath clangPlusPlusPath(const FilePath &clangPath) { - return typeIdFromMap(data) == Constants::ANDROID_TOOLCHAIN_ID; -} - -ToolChain *AndroidToolChainFactory::restore(const QVariantMap &data) -{ - auto tc = new AndroidToolChain(); - if (tc->fromMap(data)) - return tc; - - delete tc; - return nullptr; -} - -static FileName clangPlusPlusPath(const FileName &clangPath) -{ - return clangPath.parentDir().appendPath( + return clangPath.parentDir().pathAppended( HostOsInfo::withExecutableSuffix( QFileInfo(clangPath.toString()).baseName() + "++")); } @@ -191,7 +172,7 @@ static FileName clangPlusPlusPath(const FileName &clangPath) ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(CToolChainList &alreadyKnown) { QList<ToolChain *> result; - FileName clangPath = AndroidConfigurations::currentConfig().clangPath(); + FilePath clangPath = AndroidConfigurations::currentConfig().clangPath(); if (!clangPath.exists()) { qCDebug(androidTCLog) << "Clang toolchains detection fails. Can not find Clang"<< clangPath; return result; @@ -201,7 +182,7 @@ ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(CToolChainList << AndroidConfigurations::currentConfig().ndkLocation(); for (const Core::Id &lang : LanguageIds) { - FileName compilerCommand = clangPath; + FilePath compilerCommand = clangPath; if (lang == ProjectExplorer::Constants::CXX_LANGUAGE_ID) compilerCommand = clangPlusPlusPath(clangPath); @@ -214,12 +195,22 @@ ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(CToolChainList auto targetItr = ClangTargets.constBegin(); while (targetItr != ClangTargets.constEnd()) { const Abi &abi = targetItr.value(); - ToolChain *tc = findToolChain(compilerCommand, lang, targetItr.key(), alreadyKnown); + const QString target = targetItr.key(); + ToolChain *tc = findToolChain(compilerCommand, lang, target, alreadyKnown); if (tc) { qCDebug(androidTCLog) << "Tool chain already known" << abi.toString() << lang; } else { qCDebug(androidTCLog) << "New Clang toolchain found" << abi.toString() << lang; - auto atc = new AndroidToolChain(targetItr.key(), lang); + auto atc = new AndroidToolChain; + atc->setOriginalTargetTriple(target); + atc->setLanguage(lang); + atc->setTargetAbi(ClangTargets[target]); + atc->setPlatformCodeGenFlags({"-target", target}); + atc->setPlatformLinkerFlags({"-target", target}); + atc->setDetection(ToolChain::AutoDetection); + atc->setDisplayName(QString("Android Clang (%1, %2)") + .arg(ToolChainManager::displayNameOfLanguageId(lang), + AndroidConfig::displayName(abi))); atc->resetToolChain(compilerCommand); tc = atc; } @@ -233,23 +224,10 @@ ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(CToolChainList // for fromMap AndroidToolChain::AndroidToolChain() - : ClangToolChain(Constants::ANDROID_TOOLCHAIN_ID, ToolChain::ManualDetection) + : ClangToolChain(Constants::ANDROID_TOOLCHAIN_ID) { } -AndroidToolChain::AndroidToolChain(const QString& target, Core::Id languageId) - : ClangToolChain(Constants::ANDROID_TOOLCHAIN_ID, ToolChain::AutoDetection) -{ - setOriginalTargetTriple(target); - setLanguage(languageId); - setTargetAbi(ClangTargets[target]); - setPlatformCodeGenFlags({"-target", target}); - setPlatformLinkerFlags({"-target", target}); - setDisplayName(QString::fromLatin1("Android Clang (%1, %2)") - .arg(ToolChainManager::displayNameOfLanguageId(languageId), - AndroidConfig::displayName(targetAbi()))); -} - } // namespace Internal } // namespace Android diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index b8dbe4c6c2..1665f49b6a 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -42,10 +42,10 @@ public: bool isValid() const override; void addToEnvironment(Utils::Environment &env) const override; - Utils::FileName suggestedDebugger() const override; - Utils::FileName suggestedGdbServer() const; - Utils::FileNameList suggestedMkspecList() const override; - QString makeCommand(const Utils::Environment &environment) const override; + Utils::FilePath suggestedDebugger() const override; + Utils::FilePath suggestedGdbServer() const; + QStringList suggestedMkspecList() const override; + Utils::FilePath makeCommand(const Utils::Environment &environment) const override; bool fromMap(const QVariantMap &data) override; protected: @@ -53,7 +53,6 @@ protected: private: explicit AndroidToolChain(); - AndroidToolChain(const QString &target, Core::Id languageId); friend class AndroidToolChainFactory; }; @@ -64,17 +63,14 @@ class AndroidToolChainFactory : public ProjectExplorer::ToolChainFactory public: AndroidToolChainFactory(); - QSet<Core::Id> supportedLanguages() const override; ToolChainList autoDetect(CToolChainList &alreadyKnown) override; - bool canRestore(const QVariantMap &data) override; - ProjectExplorer::ToolChain *restore(const QVariantMap &data) override; class AndroidToolChainInformation { public: Core::Id language; - Utils::FileName compilerCommand; + Utils::FilePath compilerCommand; ProjectExplorer::Abi abi; QString version; }; diff --git a/src/plugins/android/androidtoolmanager.cpp b/src/plugins/android/androidtoolmanager.cpp index b547145772..be26329f98 100644 --- a/src/plugins/android/androidtoolmanager.cpp +++ b/src/plugins/android/androidtoolmanager.cpp @@ -46,7 +46,7 @@ using namespace Utils; class AndroidToolOutputParser { public: - void parseTargetListing(const QString &output, const FileName &sdkLocation, + void parseTargetListing(const QString &output, const FilePath &sdkLocation, SdkPlatformList &platformList); QList<SdkPlatform> m_installedPlatforms; @@ -57,7 +57,7 @@ public: environment. Returns \c true for successful execution. Command's output is copied to \a output. */ -static bool androidToolCommand(Utils::FileName toolPath, const QStringList &args, +static bool androidToolCommand(Utils::FilePath toolPath, const QStringList &args, const QProcessEnvironment &environment, QString *output) { QString androidToolPath = toolPath.toString(); @@ -143,7 +143,7 @@ QFuture<AndroidDeviceInfoList> AndroidToolManager::androidVirtualDevicesFuture() AndroidConfigurations::toolsEnvironment(m_config)); } -CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FileName androidToolPath, +CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FilePath androidToolPath, QProcessEnvironment env) { QProcess proc; @@ -195,8 +195,8 @@ CreateAvdInfo AndroidToolManager::createAvdImpl(CreateAvdInfo info, FileName and return info; } -AndroidDeviceInfoList AndroidToolManager::androidVirtualDevices(const Utils::FileName &androidTool, - const FileName &sdkLocationPath, +AndroidDeviceInfoList AndroidToolManager::androidVirtualDevices(const Utils::FilePath &androidTool, + const FilePath &sdkLocationPath, const QProcessEnvironment &env) { AndroidDeviceInfoList devices; @@ -244,9 +244,8 @@ AndroidDeviceInfoList AndroidToolManager::androidVirtualDevices(const Utils::Fil if (lastIndex == -1) // skip line break; QString tmp = line.mid(lastIndex).remove(QLatin1Char(')')).trimmed(); - Utils::FileName platformPath = sdkLocationPath; - platformPath.appendPath(QString("/platforms/android-%1").arg(tmp)); - dev.sdk = AndroidManager::findApiLevel(platformPath); + dev.sdk = AndroidManager::findApiLevel( + sdkLocationPath.pathAppended(QString("/platforms/android-%1").arg(tmp))); } if (line.contains(QLatin1String("Tag/ABI:"))) { int lastIndex = line.lastIndexOf(QLatin1Char('/')) + 1; @@ -275,7 +274,7 @@ AndroidDeviceInfoList AndroidToolManager::androidVirtualDevices(const Utils::Fil } void AndroidToolOutputParser::parseTargetListing(const QString &output, - const Utils::FileName &sdkLocation, + const Utils::FilePath &sdkLocation, SdkPlatformList &platformList) { auto addSystemImage = [](const QStringList& abiList, SdkPlatform *platform) { @@ -292,7 +291,7 @@ void AndroidToolOutputParser::parseTargetListing(const QString &output, QVersionNumber revision; int apiLevel = -1; QString description; - Utils::FileName installedLocation; + Utils::FilePath installedLocation; void clear() { abiList.clear(); @@ -312,10 +311,8 @@ void AndroidToolOutputParser::parseTargetListing(const QString &output, continue; QString androidTarget = line.mid(index + 1, line.length() - index - 2); const QString tmp = androidTarget.mid(androidTarget.lastIndexOf(QLatin1Char('-')) + 1); - Utils::FileName platformPath = sdkLocation; - platformPath.appendPath(QString("/platforms/android-%1").arg(tmp)); - platformParams.installedLocation = platformPath; - platformParams.apiLevel = AndroidManager::findApiLevel(platformPath); + platformParams.installedLocation = sdkLocation.pathAppended(QString("/platforms/android-%1").arg(tmp)); + platformParams.apiLevel = AndroidManager::findApiLevel(platformParams.installedLocation); } else if (line.startsWith(QLatin1String("Name:"))) { platformParams.description = line.mid(6); } else if (line.startsWith(QLatin1String("Revision:"))) { diff --git a/src/plugins/android/androidtoolmanager.h b/src/plugins/android/androidtoolmanager.h index 76cff1881e..61db46cee2 100644 --- a/src/plugins/android/androidtoolmanager.h +++ b/src/plugins/android/androidtoolmanager.h @@ -58,10 +58,10 @@ public: // Helper methods private: - static CreateAvdInfo createAvdImpl(CreateAvdInfo info, Utils::FileName androidToolPath, + static CreateAvdInfo createAvdImpl(CreateAvdInfo info, Utils::FilePath androidToolPath, QProcessEnvironment env); - static AndroidDeviceInfoList androidVirtualDevices(const Utils::FileName &androidTool, - const Utils::FileName &sdkLlocationPath, + static AndroidDeviceInfoList androidVirtualDevices(const Utils::FilePath &androidTool, + const Utils::FilePath &sdkLlocationPath, const QProcessEnvironment &env); private: const AndroidConfig &m_config; diff --git a/src/plugins/android/avddialog.cpp b/src/plugins/android/avddialog.cpp index 7097f5c1c6..c0f692734c 100644 --- a/src/plugins/android/avddialog.cpp +++ b/src/plugins/android/avddialog.cpp @@ -51,8 +51,8 @@ AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStri m_hideTipTimer.setSingleShot(true); if (targetArch.isEmpty()) { - m_avdDialog.abiComboBox->addItems(QStringList({"armeabi-v7a", "armeabi", "x86", "mips", - "arm64-v8a", "x86_64", "mips64"})); + m_avdDialog.abiComboBox->addItems(QStringList({"armeabi-v7a", "armeabi", "x86", + "arm64-v8a", "x86_64"})); } else { m_avdDialog.abiComboBox->addItems(QStringList(targetArch)); } @@ -66,7 +66,7 @@ AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStri updateApiLevelComboBox(); connect(m_avdDialog.abiComboBox, - static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AvdDialog::updateApiLevelComboBox); connect(&m_hideTipTimer, &QTimer::timeout, diff --git a/src/plugins/android/createandroidmanifestwizard.cpp b/src/plugins/android/createandroidmanifestwizard.cpp index 079fd5bd64..ca386fa907 100644 --- a/src/plugins/android/createandroidmanifestwizard.cpp +++ b/src/plugins/android/createandroidmanifestwizard.cpp @@ -86,8 +86,7 @@ ChooseProFilePage::ChooseProFilePage(CreateAndroidManifestWizard *wizard) currentBuildTarget = rc->buildKey(); m_comboBox = new QComboBox(this); - const BuildTargetInfoList buildTargets = wizard->target()->applicationTargets(); - for (const BuildTargetInfo &bti : buildTargets.list) { + for (const BuildTargetInfo &bti : wizard->target()->applicationTargets()) { const QString displayName = bti.buildKey; m_comboBox->addItem(displayName, QVariant(bti.buildKey)); // TODO something more? if (bti.buildKey == currentBuildTarget) @@ -95,7 +94,7 @@ ChooseProFilePage::ChooseProFilePage(CreateAndroidManifestWizard *wizard) } nodeSelected(m_comboBox->currentIndex()); - connect(m_comboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + connect(m_comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ChooseProFilePage::nodeSelected); fl->addRow(tr(".pro file:"), m_comboBox); @@ -157,7 +156,7 @@ ChooseDirectoryPage::ChooseDirectoryPage(CreateAndroidManifestWizard *wizard) void ChooseDirectoryPage::checkPackageSourceDir() { const QString buildKey = m_wizard->buildKey(); - const BuildTargetInfo bti = m_wizard->target()->applicationTargets().buildTargetInfo(buildKey); + const BuildTargetInfo bti = m_wizard->target()->buildTarget(buildKey); const QString projectDir = bti.projectFilePath.toFileInfo().absolutePath(); const QString newDir = m_androidPackageSourceDir->path(); @@ -181,7 +180,7 @@ void ChooseDirectoryPage::initializePage() { const Target *target = m_wizard->target(); const QString buildKey = m_wizard->buildKey(); - const BuildTargetInfo bti = target->applicationTargets().buildTargetInfo(buildKey); + const BuildTargetInfo bti = target->buildTarget(buildKey); const QString projectDir = bti.projectFilePath.toFileInfo().absolutePath(); QString androidPackageDir; @@ -214,15 +213,15 @@ CreateAndroidManifestWizard::CreateAndroidManifestWizard(ProjectExplorer::Target { setWindowTitle(tr("Create Android Template Files Wizard")); - const BuildTargetInfoList buildTargets = target->applicationTargets(); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit()); + const QList<BuildTargetInfo> buildTargets = target->applicationTargets(); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); m_copyGradle = version && version->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0); - if (buildTargets.list.isEmpty()) { + if (buildTargets.isEmpty()) { // oh uhm can't create anything addPage(new NoApplicationProFilePage(this)); - } else if (buildTargets.list.size() == 1) { - setBuildKey(buildTargets.list.first().buildKey); + } else if (buildTargets.size() == 1) { + setBuildKey(buildTargets.first().buildKey); addPage(new ChooseDirectoryPage(this)); } else { addPage(new ChooseProFilePage(this)); @@ -319,28 +318,28 @@ void CreateAndroidManifestWizard::createAndroidTemplateFiles() return; QStringList addedFiles; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(m_target->kit()); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(m_target->kit()); if (!version) return; if (version->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) { const QString src(version->qmakeProperty("QT_INSTALL_PREFIX") .append(QLatin1String("/src/android/java/AndroidManifest.xml"))); - FileUtils::copyRecursively(FileName::fromString(src), - FileName::fromString(m_directory + QLatin1String("/AndroidManifest.xml")), + FileUtils::copyRecursively(FilePath::fromString(src), + FilePath::fromString(m_directory + QLatin1String("/AndroidManifest.xml")), nullptr, [this, &addedFiles](QFileInfo src, QFileInfo dst, QString *){return copy(src, dst, &addedFiles);}); } else { const QString src(version->qmakeProperty("QT_INSTALL_PREFIX") .append(QLatin1String("/src/android/templates"))); - FileUtils::copyRecursively(FileName::fromString(src), - FileName::fromString(m_directory), + FileUtils::copyRecursively(FilePath::fromString(src), + FilePath::fromString(m_directory), nullptr, [this, &addedFiles](QFileInfo src, QFileInfo dst, QString *){return copy(src, dst, &addedFiles);}); if (m_copyGradle) { - FileName gradlePath = FileName::fromString(version->qmakeProperty("QT_INSTALL_PREFIX").append(QLatin1String("/src/3rdparty/gradle"))); + FilePath gradlePath = FilePath::fromString(version->qmakeProperty("QT_INSTALL_PREFIX").append(QLatin1String("/src/3rdparty/gradle"))); if (!gradlePath.exists()) - gradlePath = AndroidConfigurations::currentConfig().sdkLocation().appendPath(QLatin1String("/tools/templates/gradle/wrapper")); - FileUtils::copyRecursively(gradlePath, FileName::fromString(m_directory), + gradlePath = AndroidConfigurations::currentConfig().sdkLocation().pathAppended("/tools/templates/gradle/wrapper"); + FileUtils::copyRecursively(gradlePath, FilePath::fromString(m_directory), nullptr, [this, &addedFiles](QFileInfo src, QFileInfo dst, QString *){return copy(src, dst, &addedFiles);}); } @@ -357,7 +356,7 @@ void CreateAndroidManifestWizard::createAndroidTemplateFiles() if (androidPackageDir.isEmpty()) { // and now time for some magic - const BuildTargetInfo bti = m_target->applicationTargets().buildTargetInfo(m_buildKey); + const BuildTargetInfo bti = m_target->buildTarget(m_buildKey); const QString value = "$$PWD/" + bti.projectFilePath.toFileInfo().absoluteDir().relativeFilePath(m_directory); bool result = node->setData(Android::Constants::AndroidPackageSourceDir, value); diff --git a/src/plugins/android/javaparser.cpp b/src/plugins/android/javaparser.cpp index 0e89ba00ea..d6c0a8d254 100644 --- a/src/plugins/android/javaparser.cpp +++ b/src/plugins/android/javaparser.cpp @@ -53,12 +53,12 @@ void JavaParser::setProjectFileList(const QStringList &fileList) m_fileList = fileList; } -void JavaParser::setBuildDirectory(const Utils::FileName &buildDirectory) +void JavaParser::setBuildDirectory(const Utils::FilePath &buildDirectory) { m_buildDirectory = buildDirectory; } -void JavaParser::setSourceDirectory(const Utils::FileName &sourceDirectory) +void JavaParser::setSourceDirectory(const Utils::FilePath &sourceDirectory) { m_sourceDirectory = sourceDirectory; } @@ -70,17 +70,16 @@ void JavaParser::parse(const QString &line) int lineno = m_javaRegExp.cap(3).toInt(&ok); if (!ok) lineno = -1; - Utils::FileName file = Utils::FileName::fromUserInput(m_javaRegExp.cap(2)); + Utils::FilePath file = Utils::FilePath::fromUserInput(m_javaRegExp.cap(2)); if (file.isChildOf(m_buildDirectory)) { - Utils::FileName relativePath = file.relativeChildPath(m_buildDirectory); - file = m_sourceDirectory; - file.appendPath(relativePath.toString()); + Utils::FilePath relativePath = file.relativeChildPath(m_buildDirectory); + file = m_sourceDirectory.pathAppended(relativePath.toString()); } if (file.toFileInfo().isRelative()) { for (int i = 0; i < m_fileList.size(); i++) if (m_fileList[i].endsWith(file.toString())) { - file = Utils::FileName::fromString(m_fileList[i]); + file = Utils::FilePath::fromString(m_fileList[i]); break; } } diff --git a/src/plugins/android/javaparser.h b/src/plugins/android/javaparser.h index 5199f1057a..ee9a53df1f 100644 --- a/src/plugins/android/javaparser.h +++ b/src/plugins/android/javaparser.h @@ -43,16 +43,16 @@ public: void stdError(const QString &line) override; void setProjectFileList(const QStringList &fileList); - void setBuildDirectory(const Utils::FileName &buildDirectory); - void setSourceDirectory(const Utils::FileName &sourceDirectory); + void setBuildDirectory(const Utils::FilePath &buildDirectory); + void setSourceDirectory(const Utils::FilePath &sourceDirectory); private: void parse(const QString &line); QRegExp m_javaRegExp; QStringList m_fileList; - Utils::FileName m_sourceDirectory; - Utils::FileName m_buildDirectory; + Utils::FilePath m_sourceDirectory; + Utils::FilePath m_buildDirectory; }; } // namespace Internal |