From 963a31c0f4b48c3734352706fbbdae69f19b59eb Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Tue, 22 Jun 2021 19:34:12 +0300 Subject: [PATCH] Android: Make the manifest less to scary to read and edit Remove unnecessary elements from the manifest file, making it easier to manage and read. Mostly, the removed elements are more internal data that is populated by the build system and the user shouldn't have to worry or confront that. Also, use the same formatting used by Android Studio. [ChangeLog][Android] Remove some elements from the manifest file that are internal, to make it easier to deal with the manifest. Pick-to: 6.2 Change-Id: I6a1f275b579370972c0bf022502a8fbfe7d0bfd1 Reviewed-by: BogDan Vatra --- .../qt/android/bindings/QtLoader.java | 82 +++++++------- src/android/templates/AndroidManifest.xml | 101 ++++++++++-------- src/android/templates/res/values/libs.xml | 6 +- src/tools/androiddeployqt/main.cpp | 23 ++-- 4 files changed, 113 insertions(+), 99 deletions(-) diff --git a/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java index 7a122f658a3..ef53e91babb 100644 --- a/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java +++ b/src/android/java/src/org/qtproject/qt/android/bindings/QtLoader.java @@ -1,4 +1,5 @@ /* + Copyright (C) 2021 The Qt Company Ltd. Copyright (c) 2019, BogDan Vatra Contact: http://www.qt.io/licensing/ @@ -42,6 +43,7 @@ import android.content.ContextWrapper; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ComponentInfo; +import android.content.res.Resources; import android.os.Build; import android.os.Bundle; import android.util.Log; @@ -170,28 +172,29 @@ public abstract class QtLoader { // this function is used to load and start the loader private void loadApplication(Bundle loaderParams) { + final Resources resources = m_context.getResources(); + final String packageName = m_context.getPackageName(); try { final int errorCode = loaderParams.getInt(ERROR_CODE_KEY); if (errorCode != 0) { // fatal error, show the error and quit AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); errorDialog.setMessage(loaderParams.getString(ERROR_MESSAGE_KEY)); - errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); + errorDialog.setButton(resources.getString(android.R.string.ok), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); errorDialog.show(); return; } // add all bundled Qt libs to loader params - ArrayList libs = new ArrayList(); - if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) { - int resourceId = m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id"); - libs.addAll(prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))); - } + int id = resources.getIdentifier("bundled_libs", "array", packageName); + final String[] bundledLibs = resources.getStringArray(id); + ArrayList libs = new ArrayList<>(prefferedAbiLibs(bundledLibs)); String libName = null; if (m_contextInfo.metaData.containsKey("android.app.lib_name")) { @@ -225,17 +228,16 @@ public abstract class QtLoader { } catch (Exception e) { e.printStackTrace(); AlertDialog errorDialog = new AlertDialog.Builder(m_context).create(); - if (m_contextInfo.metaData.containsKey("android.app.fatal_error_msg")) - errorDialog.setMessage(m_contextInfo.metaData.getString("android.app.fatal_error_msg")); - else - errorDialog.setMessage("Fatal error, your application can't be started."); - - errorDialog.setButton(m_context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); + int id = resources.getIdentifier("fatal_error_msg", "string", + packageName); + errorDialog.setMessage(resources.getString(id)); + errorDialog.setButton(resources.getString(android.R.string.ok), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }); errorDialog.show(); } } @@ -243,14 +245,16 @@ public abstract class QtLoader { public void startApp(final boolean firstStart) { try { - if (m_contextInfo.metaData.containsKey("android.app.qt_libs_resource_id")) { - int resourceId = m_contextInfo.metaData.getInt("android.app.qt_libs_resource_id"); - m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId)); - } + final Resources resources = m_context.getResources(); + final String packageName = m_context.getPackageName(); + int id = resources.getIdentifier("qt_libs", "array", packageName); + m_qtLibs = prefferedAbiLibs(resources.getStringArray(id)); - if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs") - && m_contextInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) { - ArrayList libraryList = new ArrayList(); + id = resources.getIdentifier("use_local_qt_libs", "string", packageName); + final int useLocalLibs = Integer.parseInt(resources.getString(id)); + + if (useLocalLibs == 1) { + ArrayList libraryList = new ArrayList<>(); boolean apkDeployFromSystem = false; String apkPath = m_context.getApplicationInfo().publicSourceDir; @@ -293,10 +297,13 @@ public abstract class QtLoader { libraryList.add(libPrefix + lib + ".so"); } - if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs") - && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { - int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id"); - for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) { + id = resources.getIdentifier("bundle_local_qt_libs", "string", packageName); + final int bundleLocalLibs = Integer.parseInt(resources.getString(id)); + + if (bundleLocalLibs == 1) { + id = resources.getIdentifier("load_local_libs", "array", packageName); + ArrayList localLibs = prefferedAbiLibs(resources.getStringArray(id)); + for (String libs : localLibs) { for (String lib : libs.split(":")) { if (!lib.isEmpty()) libraryList.add(libsDir + lib); @@ -310,10 +317,11 @@ public abstract class QtLoader { loaderParams.putInt(ERROR_CODE_KEY, 0); loaderParams.putString(DEX_PATH_KEY, new String()); loaderParams.putString(LOADER_CLASS_NAME_KEY, loaderClassName()); - if (m_contextInfo.metaData.containsKey("android.app.static_init_classes")) { - loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, - m_contextInfo.metaData.getString("android.app.static_init_classes").split(":")); - } + + id = resources.getIdentifier("static_init_classes", "string", packageName); + loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, resources.getString(id) + .split(":")); + loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList); diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index fa520d0345b..d3522093396 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -1,75 +1,82 @@ - - + + - + - - - + + + - - - - - - - - + + + - - - - - - - - - - - + - - - - - + + + + + - + "applicationStateChanged(Qt::ApplicationSuspended)" signal is sent! --> + - + * none - useful for apps that don't use any of the above Qt modules --> + - - - - + - diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml index 280c03c6867..beb15ca1d8b 100644 --- a/src/android/templates/res/values/libs.xml +++ b/src/android/templates/res/values/libs.xml @@ -1,7 +1,6 @@ - + @@ -15,4 +14,7 @@ + + + diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 406acaf54d4..7993a0cfb87 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -235,7 +235,6 @@ struct Options bool usesOpenGL = false; // Per package collected information - QStringList localJars; QStringList initClasses; QStringList permissions; QStringList features; @@ -1411,10 +1410,20 @@ bool updateLibsXml(Options *options) allLocalLibs += QLatin1String(" %1;%2\n").arg(it.key(), localLibs.join(QLatin1Char(':'))); } + options->initClasses.removeDuplicates(); + QHash replacements; replacements[QStringLiteral("")] += qtLibs.trimmed(); replacements[QStringLiteral("")] = allLocalLibs.trimmed(); replacements[QStringLiteral("")] = extraLibs.trimmed(); + const QString initClasses = options->initClasses.join(QLatin1Char(':')); + replacements[QStringLiteral("")] = initClasses; + + // Bundle and use libs from the apk because currently we don't have a way avoid + // duplicating them. + replacements[QStringLiteral("")] = QLatin1String("1"); + replacements[QStringLiteral("")] = QLatin1String("1"); + if (!updateFile(fileName, replacements)) return false; @@ -1456,22 +1465,13 @@ bool updateAndroidManifest(Options &options) if (options.verbose) fprintf(stdout, " -- AndroidManifest.xml \n"); - options.localJars.removeDuplicates(); - options.initClasses.removeDuplicates(); - QHash replacements; replacements[QStringLiteral("-- %%INSERT_APP_NAME%% --")] = options.applicationBinary; replacements[QStringLiteral("-- %%INSERT_APP_ARGUMENTS%% --")] = options.applicationArguments; replacements[QStringLiteral("-- %%INSERT_APP_LIB_NAME%% --")] = options.applicationBinary; - replacements[QStringLiteral("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':')); - replacements[QStringLiteral("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':')); replacements[QStringLiteral("-- %%INSERT_VERSION_NAME%% --")] = options.versionName; replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode; replacements[QStringLiteral("package=\"org.qtproject.example\"")] = QLatin1String("package=\"%1\"").arg(options.packageName); - replacements[QStringLiteral("-- %%BUNDLE_LOCAL_QT_LIBS%% --")] - = (options.deploymentMechanism == Options::Bundled) ? QLatin1String("1") : QLatin1String("0"); - // use libs from the apk - replacements[QStringLiteral("-- %%USE_LOCAL_QT_LIBS%% --")] = QLatin1String("1"); QString permissions; for (const QString &permission : qAsConst(options.permissions)) @@ -1664,9 +1664,6 @@ bool readAndroidDependencyXml(Options *options, } } - if (!fileName.isEmpty()) - options->localJars.append(fileName); - if (reader.attributes().hasAttribute(QLatin1String("initClass"))) { options->initClasses.append(reader.attributes().value(QLatin1String("initClass")).toString()); }