aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVikas Pachdha <vikas.pachdha@qt.io>2018-07-03 11:53:25 +0200
committerVikas Pachdha <vikas.pachdha@qt.io>2018-07-09 08:57:49 +0000
commit42754374b00f9101a82029c56bd5bf3e6d03f292 (patch)
tree2e43cc250ac1776664e3d339181098acdf18d509 /src
parentf19a6e8ac2c76e323875e4dc02b53c58aa887afe (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.cpp11
-rw-r--r--src/plugins/android/androidconfigurations.h1
-rw-r--r--src/plugins/android/androidmanager.cpp69
-rw-r--r--src/plugins/android/androidmanager.h9
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 &regEx) {
+ 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