diff options
Diffstat (limited to 'src/plugins/android/androidmanager.cpp')
-rw-r--r-- | src/plugins/android/androidmanager.cpp | 167 |
1 files changed, 79 insertions, 88 deletions
diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 4fd6c7504b..56726d774d 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -52,6 +52,7 @@ #include <utils/algorithm.h> #include <utils/qtcassert.h> +#include <utils/stringutils.h> #include <utils/synchronousprocess.h> #include <QApplication> @@ -64,67 +65,62 @@ #include <QLoggingCategory> #include <QMessageBox> #include <QProcess> -#include <QRegExp> #include <QRegularExpression> #include <QVersionNumber> -namespace { - const QLatin1String AndroidManifestName("AndroidManifest.xml"); - const QLatin1String AndroidDefaultPropertiesName("project.properties"); - const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber"); - const QLatin1String AndroidDeviceAbis("AndroidDeviceAbis"); - const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel"); - const QString packageNameRegEx("(?<token>package: )(.*?)(name=)'(?<target>.*?)'"); - const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'"); - const QString apkVersionRegEx("(?<token>package: )(.*?)(versionCode=)'(?<target>.*?)'"); - const QString versionCodeRegEx("(?<token>versionCode=)(?<version>\\d*)"); - const QString qtcSignature("This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."); - - static Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager", QtWarningMsg) - - QString parseAaptOutput(const QString &output, const QString ®Ex) { - const QRegularExpression regRx(regEx, - QRegularExpression::CaseInsensitiveOption | - QRegularExpression::MultilineOption); - QRegularExpressionMatch match = regRx.match(output); - if (match.hasMatch()) - return match.captured("target"); - return QString(); - }; -} // anonymous namespace - - using namespace ProjectExplorer; using namespace Utils; +using namespace Android::Internal; + namespace Android { -using namespace Internal; +const QLatin1String AndroidManifestName("AndroidManifest.xml"); +const QLatin1String AndroidDefaultPropertiesName("project.properties"); +const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber"); +const QLatin1String AndroidDeviceAbis("AndroidDeviceAbis"); +const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel"); +const QString packageNameRegEx("(?<token>package: )(.*?)(name=)'(?<target>.*?)'"); +const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'"); +const QString apkVersionRegEx("(?<token>package: )(.*?)(versionCode=)'(?<target>.*?)'"); +const QString versionCodeRegEx("(?<token>versionCode=)(?<version>\\d*)"); +const QString qtcSignature("This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."); + +static Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager", QtWarningMsg) + +static QString parseAaptOutput(const QString &output, const QString ®Ex) +{ + const QRegularExpression regRx(regEx, + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::MultilineOption); + QRegularExpressionMatch match = regRx.match(output); + if (match.hasMatch()) + return match.captured("target"); + return QString(); +} class Library { public: - Library() - { level = -1; } - int level; + int level = -1; QStringList dependencies; QString name; }; using LibrariesMap = QMap<QString, Library>; -static bool openXmlFile(QDomDocument &doc, const Utils::FilePath &fileName); -static bool openManifest(ProjectExplorer::Target *target, QDomDocument &doc); +static bool openXmlFile(QDomDocument &doc, const FilePath &fileName); +static bool openManifest(const Target *target, QDomDocument &doc); static int parseMinSdk(const QDomElement &manifestElem); -static const ProjectNode *currentProjectNode(Target *target) +static const ProjectNode *currentProjectNode(const Target *target) { if (RunConfiguration *rc = target->activeRunConfiguration()) return target->project()->findNodeForBuildKey(rc->buildKey()); return nullptr; } -QString AndroidManager::packageName(ProjectExplorer::Target *target) +QString AndroidManager::packageName(const Target *target) { QDomDocument doc; if (!openManifest(target, doc)) @@ -133,7 +129,7 @@ QString AndroidManager::packageName(ProjectExplorer::Target *target) return manifestElem.attribute(QLatin1String("package")); } -QString AndroidManager::packageName(const Utils::FilePath &manifestFile) +QString AndroidManager::packageName(const FilePath &manifestFile) { QDomDocument doc; if (!openXmlFile(doc, manifestFile)) @@ -150,7 +146,7 @@ bool AndroidManager::packageInstalled(const QString &deviceSerial, QStringList args = AndroidDeviceInfo::adbSelector(deviceSerial); args << "shell" << "pm" << "list" << "packages"; QStringList lines = runAdbCommand(args).stdOut().split(QRegularExpression("[\\n\\r]"), - QString::SkipEmptyParts); + Utils::SkipEmptyParts); for (const QString &line : lines) { // Don't want to confuse com.abc.xyz with com.abc.xyz.def so check with // endsWith @@ -178,10 +174,10 @@ int AndroidManager::packageVersionCode(const QString &deviceSerial, return -1; } -void AndroidManager::apkInfo(const Utils::FilePath &apkPath, - QString *packageName, - int *version, - QString *activityPath) +void AndroidManager::apkInfo(const FilePath &apkPath, + QString *packageName, + int *version, + QString *activityPath) { SdkToolResult result; result = runAaptCommand({"dump", "badging", apkPath.toString()}); @@ -205,12 +201,7 @@ void AndroidManager::apkInfo(const Utils::FilePath &apkPath, } } -QString AndroidManager::intentName(ProjectExplorer::Target *target) -{ - return packageName(target) + QLatin1Char('/') + activityName(target); -} - -QString AndroidManager::activityName(ProjectExplorer::Target *target) +QString AndroidManager::activityName(const Target *target) { QDomDocument doc; if (!openManifest(target, doc)) @@ -224,7 +215,7 @@ QString AndroidManager::activityName(ProjectExplorer::Target *target) of the kit is returned if the manifest file of the APK cannot be found or parsed. */ -int AndroidManager::minimumSDK(ProjectExplorer::Target *target) +int AndroidManager::minimumSDK(const Target *target) { QDomDocument doc; if (!openXmlFile(doc, AndroidManager::manifestSourcePath(target))) @@ -236,12 +227,12 @@ int AndroidManager::minimumSDK(ProjectExplorer::Target *target) Returns the minimum Android API level required by the kit to compile. -1 is returned if the kit does not support Android. */ -int AndroidManager::minimumSDK(const ProjectExplorer::Kit *kit) +int AndroidManager::minimumSDK(const Kit *kit) { int minSDKVersion = -1; QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(kit); if (version && version->targetDeviceTypes().contains(Constants::ANDROID_DEVICE_TYPE)) { - Utils::FilePath stockManifestFilePath = Utils::FilePath::fromUserInput( + FilePath stockManifestFilePath = FilePath::fromUserInput( version->prefix().toString() + "/src/android/templates/AndroidManifest.xml"); QDomDocument doc; if (openXmlFile(doc, stockManifestFilePath)) { @@ -251,7 +242,7 @@ int AndroidManager::minimumSDK(const ProjectExplorer::Kit *kit) return minSDKVersion; } -QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target) +QString AndroidManager::buildTargetSDK(const Target *target) { if (auto bc = target->activeBuildConfiguration()) { if (auto androidBuildApkStep = bc->buildSteps()->firstOfType<AndroidBuildApkStep>()) @@ -287,7 +278,7 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) if (!qt) return {}; - auto tc = ProjectExplorer::ToolChainKitAspect::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); + auto tc = ToolChainKitAspect::cxxToolChain(target->kit()); if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID) return {}; QJsonObject settings; @@ -298,10 +289,10 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) if (qt->qtVersion() < QtSupport::QtVersionNumber(5, 14, 0)) { const QStringList abis = applicationAbis(target); QTC_ASSERT(abis.size() == 1, return {}); - settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath(qt) - .pathAppended("sysroot/usr/lib/") - .pathAppended(archTriplet(abis.first())) - .pathAppended("libc++_shared.so").toString(); + settings["stdcpp-path"] = (AndroidConfigurations::currentConfig().toolchainPath(qt) + / "sysroot/usr/lib/" + / archTriplet(abis.first()) + / "libc++_shared.so").toString(); } else { settings["stdcpp-path"] = AndroidConfigurations::currentConfig() .toolchainPath(qt) @@ -323,23 +314,23 @@ bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile) return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature; } -Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target) +FilePath AndroidManager::dirPath(const Target *target) { if (auto *bc = target->activeBuildConfiguration()) - return bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY); - return Utils::FilePath(); + return bc->buildDirectory() / Constants::ANDROID_BUILDDIRECTORY; + return {}; } -Utils::FilePath AndroidManager::apkPath(const ProjectExplorer::Target *target) +FilePath AndroidManager::apkPath(const Target *target) { - QTC_ASSERT(target, return Utils::FilePath()); + QTC_ASSERT(target, return {}); auto bc = target->activeBuildConfiguration(); if (!bc) return {}; auto buildApkStep = bc->buildSteps()->firstOfType<AndroidBuildApkStep>(); if (!buildApkStep) - return Utils::FilePath(); + return {}; QString apkPath("build/outputs/apk/android-build-"); if (buildApkStep->signPackage()) @@ -347,7 +338,7 @@ Utils::FilePath AndroidManager::apkPath(const ProjectExplorer::Target *target) else apkPath += QLatin1String("debug.apk"); - return dirPath(target).pathAppended(apkPath); + return dirPath(target) / apkPath; } bool AndroidManager::matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis) @@ -403,7 +394,7 @@ Abi AndroidManager::androidAbi2Abi(const QString &androidAbi) } } -Utils::FilePath AndroidManager::manifestSourcePath(ProjectExplorer::Target *target) +FilePath AndroidManager::manifestSourcePath(const Target *target) { if (const ProjectNode *node = currentProjectNode(target)) { const QString packageSource @@ -417,7 +408,7 @@ Utils::FilePath AndroidManager::manifestSourcePath(ProjectExplorer::Target *targ return manifestPath(target); } -Utils::FilePath AndroidManager::manifestPath(ProjectExplorer::Target *target) +FilePath AndroidManager::manifestPath(const Target *target) { QVariant manifest = target->namedSettings(AndroidManifestName); if (manifest.isValid()) @@ -430,24 +421,24 @@ void AndroidManager::setManifestPath(Target *target, const FilePath &path) target->setNamedSettings(AndroidManifestName, QVariant::fromValue(path)); } -Utils::FilePath AndroidManager::defaultPropertiesPath(ProjectExplorer::Target *target) +FilePath AndroidManager::defaultPropertiesPath(const Target *target) { return dirPath(target).pathAppended(AndroidDefaultPropertiesName); } -QString AndroidManager::deviceSerialNumber(ProjectExplorer::Target *target) +QString AndroidManager::deviceSerialNumber(const Target *target) { return target->namedSettings(AndroidDeviceSn).toString(); } -void AndroidManager::setDeviceSerialNumber(ProjectExplorer::Target *target, const QString &deviceSerialNumber) +void AndroidManager::setDeviceSerialNumber(Target *target, const QString &deviceSerialNumber) { - qCDebug(androidManagerLog) << "Device serial for the target changed" + qCDebug(androidManagerLog) << "Target device serial changed:" << target->displayName() << deviceSerialNumber; target->setNamedSettings(AndroidDeviceSn, deviceSerialNumber); } -static QString preferredAbi(const QStringList &appAbis, Target *target) +static QString preferredAbi(const QStringList &appAbis, const Target *target) { const auto deviceAbis = target->namedSettings(AndroidDeviceAbis).toStringList(); for (const auto &abi : deviceAbis) { @@ -457,7 +448,7 @@ static QString preferredAbi(const QStringList &appAbis, Target *target) return {}; } -QString AndroidManager::apkDevicePreferredAbi(Target *target) +QString AndroidManager::apkDevicePreferredAbi(const Target *target) { auto libsPath = dirPath(target).pathAppended("libs"); QStringList apkAbis; @@ -467,19 +458,19 @@ QString AndroidManager::apkDevicePreferredAbi(Target *target) return preferredAbi(apkAbis, target); } -void AndroidManager::setDeviceAbis(ProjectExplorer::Target *target, const QStringList &deviceAbis) +void AndroidManager::setDeviceAbis(Target *target, const QStringList &deviceAbis) { target->setNamedSettings(AndroidDeviceAbis, deviceAbis); } -int AndroidManager::deviceApiLevel(ProjectExplorer::Target *target) +int AndroidManager::deviceApiLevel(const Target *target) { return target->namedSettings(ApiLevelKey).toInt(); } -void AndroidManager::setDeviceApiLevel(ProjectExplorer::Target *target, int level) +void AndroidManager::setDeviceApiLevel(Target *target, int level) { - qCDebug(androidManagerLog) << "Device API level for the target changed" + qCDebug(androidManagerLog) << "Target device API level changed:" << target->displayName() << level; target->setNamedSettings(ApiLevelKey, level); } @@ -547,7 +538,7 @@ QString AndroidManager::androidNameForApiLevel(int x) case 30: return QLatin1String("Android 11"); default: - return tr("Unknown Android version. API Level: %1").arg(QString::number(x)); + return tr("Unknown Android version. API Level: %1").arg(x); } } @@ -556,7 +547,7 @@ static void raiseError(const QString &reason) QMessageBox::critical(nullptr, AndroidManager::tr("Error creating Android templates."), reason); } -static bool openXmlFile(QDomDocument &doc, const Utils::FilePath &fileName) +static bool openXmlFile(QDomDocument &doc, const FilePath &fileName) { QFile f(fileName.toString()); if (!f.open(QIODevice::ReadOnly)) @@ -569,7 +560,7 @@ static bool openXmlFile(QDomDocument &doc, const Utils::FilePath &fileName) return true; } -static bool openManifest(ProjectExplorer::Target *target, QDomDocument &doc) +static bool openManifest(const Target *target, QDomDocument &doc) { return openXmlFile(doc, AndroidManager::manifestPath(target)); } @@ -588,7 +579,7 @@ static int parseMinSdk(const QDomElement &manifestElem) return 0; } -void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath) +void AndroidManager::installQASIPackage(Target *target, const QString &packagePath) { const QStringList appAbis = AndroidManager::applicationAbis(target); if (appAbis.isEmpty()) @@ -621,7 +612,7 @@ bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QS SynchronousProcess proc; proc.setTimeoutS(10); SynchronousProcessResponse response = proc.run(cmd); - return (response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0); + return (response.result == SynchronousProcessResponse::Finished && response.exitCode == 0); } bool AndroidManager::checkCertificatePassword(const QString &keystorePath, const QString &keystorePasswd, const QString &alias, const QString &certificatePasswd) @@ -717,7 +708,7 @@ static bool mergeGradleProperties(const QString &path, GradleProperties properti } -bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target, const QString &buildKey) +bool AndroidManager::updateGradleProperties(Target *target, const QString &buildKey) { QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); if (!version) @@ -743,7 +734,7 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target, con if (!packageSourceDir.exists()) return false; - const FilePath wrapperProps = packageSourceDir.pathAppended("gradle/wrapper/gradle-wrapper.properties"); + const FilePath wrapperProps = packageSourceDir / "gradle/wrapper/gradle-wrapper.properties"; if (wrapperProps.exists()) { GradleProperties wrapperProperties = readGradleProperties(wrapperProps.toString()); QString distributionUrl = QString::fromLocal8Bit(wrapperProperties["distributionUrl"]); @@ -756,7 +747,7 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target, con GradleProperties localProperties; localProperties["sdk.dir"] = AndroidConfigurations::currentConfig().sdkLocation().toString().toLocal8Bit(); - const FilePath localPropertiesFile = packageSourceDir.pathAppended("local.properties"); + const FilePath localPropertiesFile = packageSourceDir / "local.properties"; if (!mergeGradleProperties(localPropertiesFile.toString(), localProperties)) return false; @@ -775,10 +766,10 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target, con return mergeGradleProperties(gradlePropertiesPath, gradleProperties); } -int AndroidManager::findApiLevel(const Utils::FilePath &platformPath) +int AndroidManager::findApiLevel(const FilePath &platformPath) { int apiLevel = -1; - const Utils::FilePath propertiesPath = platformPath.pathAppended("/source.properties"); + const FilePath propertiesPath = platformPath / "/source.properties"; if (propertiesPath.exists()) { QSettings sdkProperties(propertiesPath.toString(), QSettings::IniFormat); bool validInt = false; @@ -817,14 +808,14 @@ SdkToolResult AndroidManager::runCommand(const CommandLine &command, const QByteArray &writeData, int timeoutS) { Android::SdkToolResult cmdResult; - Utils::SynchronousProcess cmdProc; + SynchronousProcess cmdProc; cmdProc.setTimeoutS(timeoutS); qCDebug(androidManagerLog) << "Running command (sync):" << command.toUserOutput(); SynchronousProcessResponse response = cmdProc.run(command, writeData); cmdResult.m_stdOut = response.stdOut().trimmed(); cmdResult.m_stdErr = response.stdErr().trimmed(); - cmdResult.m_success = response.result == Utils::SynchronousProcessResponse::Finished; - qCDebug(androidManagerLog) << "Running command (sync) finshed:" << command.toUserOutput() + cmdResult.m_success = response.result == SynchronousProcessResponse::Finished; + qCDebug(androidManagerLog) << "Command finshed (sync):" << command.toUserOutput() << "Success:" << cmdResult.m_success << "Output:" << response.allRawOutput(); if (!cmdResult.success()) |