forked from qt-creator/qt-creator
Android: Simplify reading manifest files
Change-Id: I8be86a26fd1f37ce59af7e5cdbdaf12519937da0 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include <QVersionNumber>
|
#include <QVersionNumber>
|
||||||
|
|
||||||
using namespace Android::Internal;
|
using namespace Android::Internal;
|
||||||
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -60,9 +61,32 @@ public:
|
|||||||
|
|
||||||
using LibrariesMap = QMap<QString, Library>;
|
using LibrariesMap = QMap<QString, Library>;
|
||||||
|
|
||||||
static bool openXmlFile(QDomDocument &doc, const FilePath &fileName);
|
static std::optional<QDomElement> documentElement(const FilePath &fileName)
|
||||||
static bool openManifest(const Target *target, QDomDocument &doc);
|
{
|
||||||
static int parseMinSdk(const QDomElement &manifestElem);
|
QFile file(fileName.toString());
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
MessageManager::writeDisrupting(Tr::tr("Cannot open: %1").arg(fileName.toUserOutput()));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
QDomDocument doc;
|
||||||
|
if (!doc.setContent(file.readAll())) {
|
||||||
|
MessageManager::writeDisrupting(Tr::tr("Cannot parse: %1").arg(fileName.toUserOutput()));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return doc.documentElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parseMinSdk(const QDomElement &manifestElem)
|
||||||
|
{
|
||||||
|
const QDomElement usesSdk = manifestElem.firstChildElement("uses-sdk");
|
||||||
|
if (!usesSdk.isNull() && usesSdk.hasAttribute("android:minSdkVersion")) {
|
||||||
|
bool ok;
|
||||||
|
int tmp = usesSdk.attribute("android:minSdkVersion").toInt(&ok);
|
||||||
|
if (ok)
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const ProjectNode *currentProjectNode(const Target *target)
|
static const ProjectNode *currentProjectNode(const Target *target)
|
||||||
{
|
{
|
||||||
@@ -71,30 +95,27 @@ static const ProjectNode *currentProjectNode(const Target *target)
|
|||||||
|
|
||||||
QString packageName(const Target *target)
|
QString packageName(const Target *target)
|
||||||
{
|
{
|
||||||
QDomDocument doc;
|
const auto element = documentElement(AndroidManager::manifestPath(target));
|
||||||
if (!openManifest(target, doc))
|
if (!element)
|
||||||
return {};
|
return {};
|
||||||
QDomElement manifestElem = doc.documentElement();
|
return element->attribute("package");
|
||||||
return manifestElem.attribute(QLatin1String("package"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString packageName(const FilePath &manifestFile)
|
QString packageName(const FilePath &manifestFile)
|
||||||
{
|
{
|
||||||
QDomDocument doc;
|
const auto element = documentElement(manifestFile);
|
||||||
if (!openXmlFile(doc, manifestFile))
|
if (!element)
|
||||||
return {};
|
return {};
|
||||||
QDomElement manifestElem = doc.documentElement();
|
return element->attribute("package");
|
||||||
return manifestElem.attribute(QLatin1String("package"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString activityName(const Target *target)
|
QString activityName(const Target *target)
|
||||||
{
|
{
|
||||||
QDomDocument doc;
|
const auto element = documentElement(AndroidManager::manifestPath(target));
|
||||||
if (!openManifest(target, doc))
|
if (!element)
|
||||||
return {};
|
return {};
|
||||||
QDomElement activityElem = doc.documentElement().firstChildElement(
|
return element->firstChildElement("application").firstChildElement("activity")
|
||||||
QLatin1String("application")).firstChildElement(QLatin1String("activity"));
|
.attribute("android:name");
|
||||||
return activityElem.attribute(QLatin1String("android:name"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FilePath manifestSourcePath(const Target *target)
|
static FilePath manifestSourcePath(const Target *target)
|
||||||
@@ -118,10 +139,11 @@ static FilePath manifestSourcePath(const Target *target)
|
|||||||
*/
|
*/
|
||||||
int minimumSDK(const Target *target)
|
int minimumSDK(const Target *target)
|
||||||
{
|
{
|
||||||
QDomDocument doc;
|
const auto element = documentElement(manifestSourcePath(target));
|
||||||
if (!openXmlFile(doc, manifestSourcePath(target)))
|
if (!element)
|
||||||
return minimumSDK(target->kit());
|
return minimumSDK(target->kit());
|
||||||
const int minSdkVersion = parseMinSdk(doc.documentElement());
|
|
||||||
|
const int minSdkVersion = parseMinSdk(*element);
|
||||||
if (minSdkVersion == 0)
|
if (minSdkVersion == 0)
|
||||||
return AndroidManager::defaultMinimumSDK(QtSupport::QtKitAspect::qtVersion(target->kit()));
|
return AndroidManager::defaultMinimumSDK(QtSupport::QtKitAspect::qtVersion(target->kit()));
|
||||||
return minSdkVersion;
|
return minSdkVersion;
|
||||||
@@ -136,12 +158,12 @@ int minimumSDK(const Kit *kit)
|
|||||||
int minSdkVersion = -1;
|
int minSdkVersion = -1;
|
||||||
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(kit);
|
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(kit);
|
||||||
if (version && version->targetDeviceTypes().contains(Constants::ANDROID_DEVICE_TYPE)) {
|
if (version && version->targetDeviceTypes().contains(Constants::ANDROID_DEVICE_TYPE)) {
|
||||||
FilePath stockManifestFilePath = FilePath::fromUserInput(
|
const FilePath stockManifestFilePath = FilePath::fromUserInput(
|
||||||
version->prefix().toString() + "/src/android/templates/AndroidManifest.xml");
|
version->prefix().toString() + "/src/android/templates/AndroidManifest.xml");
|
||||||
QDomDocument doc;
|
|
||||||
if (openXmlFile(doc, stockManifestFilePath)) {
|
const auto element = documentElement(stockManifestFilePath);
|
||||||
minSdkVersion = parseMinSdk(doc.documentElement());
|
if (element)
|
||||||
}
|
minSdkVersion = parseMinSdk(*element);
|
||||||
}
|
}
|
||||||
if (minSdkVersion == 0)
|
if (minSdkVersion == 0)
|
||||||
return AndroidManager::defaultMinimumSDK(version);
|
return AndroidManager::defaultMinimumSDK(version);
|
||||||
@@ -240,7 +262,7 @@ bool isQt5CmakeProject(const ProjectExplorer::Target *target)
|
|||||||
{
|
{
|
||||||
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit());
|
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||||
const bool isQt5 = qt && qt->qtVersion() < QVersionNumber(6, 0, 0);
|
const bool isQt5 = qt && qt->qtVersion() < QVersionNumber(6, 0, 0);
|
||||||
const Core::Context cmakeCtx = Core::Context(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
|
const Context cmakeCtx(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
|
||||||
const bool isCmakeProject = (target->project()->projectContext() == cmakeCtx);
|
const bool isCmakeProject = (target->project()->projectContext() == cmakeCtx);
|
||||||
return isQt5 && isCmakeProject;
|
return isQt5 && isCmakeProject;
|
||||||
}
|
}
|
||||||
@@ -371,7 +393,7 @@ bool skipInstallationAndPackageSteps(const Target *target)
|
|||||||
|
|
||||||
const Project *p = target->project();
|
const Project *p = target->project();
|
||||||
|
|
||||||
const Core::Context cmakeCtx = Core::Context(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
|
const Context cmakeCtx(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
|
||||||
const bool isCmakeProject = p->projectContext() == cmakeCtx;
|
const bool isCmakeProject = p->projectContext() == cmakeCtx;
|
||||||
if (isCmakeProject)
|
if (isCmakeProject)
|
||||||
return false; // CMake reports ProductType::Other for Android Apps
|
return false; // CMake reports ProductType::Other for Android Apps
|
||||||
@@ -538,43 +560,6 @@ QString androidNameForApiLevel(int x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raiseError(const QString &reason)
|
|
||||||
{
|
|
||||||
QMessageBox::critical(nullptr, Tr::tr("Error creating Android templates."), reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool openXmlFile(QDomDocument &doc, const FilePath &fileName)
|
|
||||||
{
|
|
||||||
QFile f(fileName.toString());
|
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!doc.setContent(f.readAll())) {
|
|
||||||
raiseError(Tr::tr("Cannot parse \"%1\".").arg(fileName.toUserOutput()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool openManifest(const Target *target, QDomDocument &doc)
|
|
||||||
{
|
|
||||||
return openXmlFile(doc, AndroidManager::manifestPath(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parseMinSdk(const QDomElement &manifestElem)
|
|
||||||
{
|
|
||||||
QDomElement usesSdk = manifestElem.firstChildElement(QLatin1String("uses-sdk"));
|
|
||||||
if (usesSdk.isNull())
|
|
||||||
return 0;
|
|
||||||
if (usesSdk.hasAttribute(QLatin1String("android:minSdkVersion"))) {
|
|
||||||
bool ok;
|
|
||||||
int tmp = usesSdk.attribute(QLatin1String("android:minSdkVersion")).toInt(&ok);
|
|
||||||
if (ok)
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void installQASIPackage(Target *target, const FilePath &packagePath)
|
void installQASIPackage(Target *target, const FilePath &packagePath)
|
||||||
{
|
{
|
||||||
const QStringList appAbis = AndroidManager::applicationAbis(target);
|
const QStringList appAbis = AndroidManager::applicationAbis(target);
|
||||||
@@ -589,7 +574,7 @@ void installQASIPackage(Target *target, const FilePath &packagePath)
|
|||||||
if (info.type == IDevice::Emulator) {
|
if (info.type == IDevice::Emulator) {
|
||||||
deviceSerialNumber = AndroidAvdManager::startAvd(info.avdName);
|
deviceSerialNumber = AndroidAvdManager::startAvd(info.avdName);
|
||||||
if (deviceSerialNumber.isEmpty())
|
if (deviceSerialNumber.isEmpty())
|
||||||
Core::MessageManager::writeDisrupting(Tr::tr("Starting Android virtual device failed."));
|
MessageManager::writeDisrupting(Tr::tr("Starting Android virtual device failed."));
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
|
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
|
||||||
@@ -600,7 +585,7 @@ void installQASIPackage(Target *target, const FilePath &packagePath)
|
|||||||
// TODO: Potential leak when the process is still running on Creator shutdown.
|
// TODO: Potential leak when the process is still running on Creator shutdown.
|
||||||
QObject::connect(process, &Process::done, process, &QObject::deleteLater);
|
QObject::connect(process, &Process::done, process, &QObject::deleteLater);
|
||||||
} else {
|
} else {
|
||||||
Core::MessageManager::writeDisrupting(
|
MessageManager::writeDisrupting(
|
||||||
Tr::tr("Android package installation failed.\n%1").arg(error));
|
Tr::tr("Android package installation failed.\n%1").arg(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user