diff options
author | Vikas Pachdha <vikas.pachdha@qt.io> | 2018-07-03 11:53:25 +0200 |
---|---|---|
committer | Vikas Pachdha <vikas.pachdha@qt.io> | 2018-07-09 08:57:49 +0000 |
commit | 42754374b00f9101a82029c56bd5bf3e6d03f292 (patch) | |
tree | 2e43cc250ac1776664e3d339181098acdf18d509 /src | |
parent | f19a6e8ac2c76e323875e4dc02b53c58aa887afe (diff) |
Android: Parse APK to find package name and other information
Task-number: QDS-16
Change-Id: I228af0711fb2dd64ff96dcb5fc9bc634b556ffd9
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/android/androidconfigurations.cpp | 11 | ||||
-rw-r--r-- | src/plugins/android/androidconfigurations.h | 1 | ||||
-rw-r--r-- | src/plugins/android/androidmanager.cpp | 69 | ||||
-rw-r--r-- | src/plugins/android/androidmanager.h | 9 |
4 files changed, 89 insertions, 1 deletions
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index c281f25dda..ed76035c27 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -416,6 +416,17 @@ FileName AndroidConfig::avdManagerToolPath() const return avdManagerPath; } +FileName AndroidConfig::aaptToolPath() const +{ + Utils::FileName aaptToolPath = m_sdkLocation; + aaptToolPath.appendPath("build-tools"); + QString toolPath = QString("%1/aapt").arg(buildToolsVersion().toString()); + if (HostOsInfo::isWindowsHost()) + toolPath += ANDROID_BAT_SUFFIX; + aaptToolPath.appendPath(toolPath); + return aaptToolPath; +} + FileName AndroidConfig::gccPath(const Abi &abi, Core::Id lang, const QString &ndkToolChainVersion) const { diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 58dde7479b..0a7fa4c3b7 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -132,6 +132,7 @@ public: Utils::FileName emulatorToolPath() const; Utils::FileName sdkManagerToolPath() const; Utils::FileName avdManagerToolPath() const; + Utils::FileName aaptToolPath() const; Utils::FileName gccPath(const ProjectExplorer::Abi &abi, Core::Id lang, const QString &ndkToolChainVersion) const; diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index c52bd5f8ee..c6f5a42e03 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -61,12 +61,19 @@ #include <QApplication> #include <QDomDocument> #include <QVersionNumber> +#include <QRegularExpression> namespace { const QLatin1String AndroidManifestName("AndroidManifest.xml"); const QLatin1String AndroidDefaultPropertiesName("project.properties"); const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber"); const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel"); + const QString packageNameRegEx("(package: name=)\\'(([a-z]{1}[a-z\\d_]*\\." + ")*[a-z][a-z\\d_]*)\\'"); + const QString activityRegEx("(launchable-activity: name=)\\'" + "(([a-z]{1}[a-z\\d_]*\\.)*[a-z][a-z\\d_]*)\\'"); + const QString apkVersionRegEx("package: name=([\\=a-z\\d_\\.\\'\\s]*)" + "\\sversionName='([\\d\\.]*)'"); Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager") @@ -82,6 +89,15 @@ namespace { return response.result == Utils::SynchronousProcessResponse::Finished; } + 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(2); + return QString(); + }; } // anonymous namespace namespace Android { @@ -134,6 +150,53 @@ QString AndroidManager::packageName(const Utils::FileName &manifestFile) return manifestElem.attribute(QLatin1String("package")); } +bool AndroidManager::packageInstalled(const QString &deviceSerial, + const QString &packageName) +{ + if (deviceSerial.isEmpty() || packageName.isEmpty()) + return false; + QStringList args = AndroidDeviceInfo::adbSelector(deviceSerial); + args << "shell" << "pm" << "list" << "packages"; + QString output; + runAdbCommand(args, &output); + QStringList lines = output.split(QRegularExpression("[\\n\\r]"), + QString::SkipEmptyParts); + for (const QString &line : lines) { + // Don't want to confuse com.abc.xyz with com.abc.xyz.def so check with + // endsWith + if (line.endsWith(packageName)) + return true; + } + return false; +} + +void AndroidManager::apkInfo(const Utils::FileName &apkPath, + QString *packageName, + QVersionNumber *version, + QString *activityPath) +{ + QString output; + runAaptCommand({"dump", "badging", apkPath.toString()}, &output); + + QString packageStr; + if (activityPath) { + packageStr = parseAaptOutput(output, packageNameRegEx); + QString path = parseAaptOutput(output, activityRegEx); + if (!packageStr.isEmpty() && !path.isEmpty()) + *activityPath = packageStr + '/' + path; + } + + if (packageName) { + *packageName = activityPath ? packageStr : + parseAaptOutput(output, packageNameRegEx); + } + + if (version) { + QString versionStr = parseAaptOutput(output, apkVersionRegEx); + *version = QVersionNumber::fromString(versionStr); + } +} + QString AndroidManager::intentName(ProjectExplorer::Target *target) { return packageName(target) + QLatin1Char('/') + activityName(target); @@ -613,4 +676,10 @@ bool AndroidManager::runAdbCommand(const QStringList &args, QString *output) return runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(), args, output); } + +bool AndroidManager::runAaptCommand(const QStringList &args, QString *output) +{ + return runCommand(AndroidConfigurations::currentConfig().aaptToolPath().toString(), + args, output); +} } // namespace Android diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 1c79a23631..fcda5e46d4 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -29,6 +29,7 @@ #include <QPair> #include <QObject> +#include <QVersionNumber> namespace ProjectExplorer { class Kit; @@ -48,7 +49,12 @@ class ANDROID_EXPORT AndroidManager : public QObject public: static QString packageName(ProjectExplorer::Target *target); static QString packageName(const Utils::FileName &manifestFile); - + static bool packageInstalled(const QString &deviceSerial, + const QString &packageName); + static void apkInfo(const Utils::FileName &apkPath, + QString *packageName = nullptr, + QVersionNumber *version = nullptr, + QString *activityPath = nullptr); static QString intentName(ProjectExplorer::Target *target); static QString activityName(ProjectExplorer::Target *target); @@ -90,6 +96,7 @@ public: static void runAdbCommandDetached(const QStringList &args); static bool runAdbCommand(const QStringList &args, QString *output = nullptr); + static bool runAaptCommand(const QStringList &args, QString *output = nullptr); }; } // namespace Android |