summaryrefslogtreecommitdiffstats
path: root/src/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/android')
-rw-r--r--src/android/jar/jar.pro1
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java19
-rw-r--r--src/android/java/java.pro2
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java306
-rw-r--r--src/android/templates/AndroidManifest.xml7
-rw-r--r--src/android/templates/build.gradle9
-rw-r--r--src/android/templates/res/values/libs.xml15
-rw-r--r--src/android/templates/templates.pro2
8 files changed, 97 insertions, 264 deletions
diff --git a/src/android/jar/jar.pro b/src/android/jar/jar.pro
index ac6fc79968..24a83d56a1 100644
--- a/src/android/jar/jar.pro
+++ b/src/android/jar/jar.pro
@@ -1,6 +1,7 @@
TARGET = QtAndroid
CONFIG += java
+
DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index c33d5016ce..7db16002ff 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -1013,6 +1013,25 @@ public class QtNative
});
}
+ private static String[] listAssetContent(android.content.res.AssetManager asset, String path) {
+ String [] list;
+ ArrayList<String> res = new ArrayList<String>();
+ try {
+ list = asset.list(path);
+ if (list.length > 0) {
+ for (String file : list) {
+ try {
+ String[] isDir = asset.list(path.length() > 0 ? path + "/" + file : file);
+ if (isDir != null && isDir.length > 0)
+ file += "/";
+ res.add(file);
+ } catch (Exception e) {}
+ }
+ }
+ } catch (Exception e) {}
+ return res.toArray(new String[res.size()]);
+ }
+
// screen methods
public static native void setDisplayMetrics(int screenWidthPixels,
int screenHeightPixels,
diff --git a/src/android/java/java.pro b/src/android/java/java.pro
index 9d37eb1026..7f0dfa8a1b 100644
--- a/src/android/java/java.pro
+++ b/src/android/java/java.pro
@@ -1,3 +1,5 @@
+CONFIG += single_arch
+
CONFIG -= qt android_install
javaresources.files = \
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
index 9d5578ed6d..1e72aa3841 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2016, BogDan Vatra <bogdan@kde.org>
+ Copyright (c) 2019, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt.io/licensing/
Commercial License Usage
@@ -44,8 +44,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ComponentInfo;
-import android.content.pm.PackageInfo;
-import android.content.res.AssetManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -55,17 +53,13 @@ import android.util.Log;
import org.kde.necessitas.ministro.IMinistro;
import org.kde.necessitas.ministro.IMinistroCallback;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
import dalvik.system.DexClassLoader;
@@ -85,9 +79,6 @@ public abstract class QtLoader {
public static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables";
public static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
public static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
- public static final String QT_LIBS_RESOURCE_ID_KEY = "android.app.qt_libs_resource_id";
- public static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id";
- public static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id";
public static final String MAIN_LIBRARY_KEY = "main.library";
public static final String STATIC_INIT_CLASSES_KEY = "static.init.classes";
public static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level";
@@ -139,7 +130,6 @@ public abstract class QtLoader {
public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme.
public static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded.
- public static final int BUFFER_SIZE = 1024;
public String[] m_sources = {"https://download.qt-project.org/ministro/android/qt5/qt-5.7"}; // Make sure you are using ONLY secure locations
public String m_repository = "default"; // Overwrites the default Ministro repository
@@ -153,12 +143,15 @@ public abstract class QtLoader {
// this repository is used to push a new release, and should be used to test your application.
// * unstable - unstable repository, DO NOT use this repository in production,
// this repository is used to push Qt snapshots.
- public String[] m_qtLibs = null; // required qt libs
+ public ArrayList<String> m_qtLibs = null; // required qt libs
public int m_displayDensity = -1;
private ContextWrapper m_context;
protected ComponentInfo m_contextInfo;
private Class<?> m_delegateClass;
+ private static ArrayList<FileOutputStream> m_fileOutputStreams = new ArrayList<FileOutputStream>();
+ // List of open file streams associated with files copied during installation.
+
QtLoader(ContextWrapper context, Class<?> clazz) {
m_context = context;
m_delegateClass = clazz;
@@ -188,6 +181,36 @@ public abstract class QtLoader {
}
// Implement in subclass
+ private final List<String> supportedAbis = Arrays.asList(Build.SUPPORTED_ABIS);
+ private String preferredAbi = null;
+
+ private ArrayList<String> prefferedAbiLibs(String []libs)
+ {
+ HashMap<String, ArrayList<String>> abisLibs = new HashMap<>();
+ for (String lib : libs) {
+ String[] archLib = lib.split(";", 2);
+ if (preferredAbi != null && !archLib[0].equals(preferredAbi))
+ continue;
+ if (!abisLibs.containsKey(archLib[0]))
+ abisLibs.put(archLib[0], new ArrayList<String>());
+ abisLibs.get(archLib[0]).add(archLib[1]);
+ }
+
+ if (preferredAbi != null) {
+ if (abisLibs.containsKey(preferredAbi)) {
+ return abisLibs.get(preferredAbi);
+ }
+ return new ArrayList<String>();
+ }
+
+ for (String abi: supportedAbis) {
+ if (abisLibs.containsKey(abi)) {
+ preferredAbi = abi;
+ return abisLibs.get(abi);
+ }
+ }
+ return new ArrayList<String>();
+ }
// this function is used to load and start the loader
private void loadApplication(Bundle loaderParams)
@@ -215,12 +238,14 @@ public abstract class QtLoader {
// add all bundled Qt libs to loader params
ArrayList<String> libs = new ArrayList<String>();
- if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id"))
- libs.addAll(Arrays.asList(m_context.getResources().getStringArray(m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id"))));
+ 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)));
+ }
String libName = null;
if (m_contextInfo.metaData.containsKey("android.app.lib_name")) {
- libName = m_contextInfo.metaData.getString("android.app.lib_name");
+ libName = m_contextInfo.metaData.getString("android.app.lib_name") + "_" + preferredAbi;
loaderParams.putString(MAIN_LIBRARY_KEY, libName); //main library contains main() function
}
@@ -275,7 +300,7 @@ public abstract class QtLoader {
try {
if (m_service != null) {
Bundle parameters = new Bundle();
- parameters.putStringArray(REQUIRED_MODULES_KEY, m_qtLibs);
+ parameters.putStringArray(REQUIRED_MODULES_KEY, (String[]) m_qtLibs.toArray());
parameters.putString(APPLICATION_TITLE_KEY, getTitle());
parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL);
parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION);
@@ -331,215 +356,6 @@ public abstract class QtLoader {
errorDialog.show();
}
- static private void copyFile(InputStream inputStream, OutputStream outputStream)
- throws IOException
- {
- byte[] buffer = new byte[BUFFER_SIZE];
-
- int count;
- while ((count = inputStream.read(buffer)) > 0)
- outputStream.write(buffer, 0, count);
- }
-
- private void copyAsset(String source, String destination)
- throws IOException
- {
- // Already exists, we don't have to do anything
- File destinationFile = new File(destination);
- if (destinationFile.exists())
- return;
-
- File parentDirectory = destinationFile.getParentFile();
- if (!parentDirectory.exists())
- parentDirectory.mkdirs();
-
- destinationFile.createNewFile();
-
- AssetManager assetsManager = m_context.getAssets();
- InputStream inputStream = null;
- OutputStream outputStream = null;
- try {
- inputStream = assetsManager.open(source);
- outputStream = new FileOutputStream(destinationFile);
- copyFile(inputStream, outputStream);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null)
- inputStream.close();
-
- if (outputStream != null)
- outputStream.close();
- }
- }
-
- private static void createBundledBinary(String source, String destination)
- throws IOException
- {
- // Already exists, we don't have to do anything
- File destinationFile = new File(destination);
- if (destinationFile.exists())
- return;
-
- File parentDirectory = destinationFile.getParentFile();
- if (!parentDirectory.exists())
- parentDirectory.mkdirs();
-
- destinationFile.createNewFile();
-
- InputStream inputStream = null;
- OutputStream outputStream = null;
- try {
- inputStream = new FileInputStream(source);
- outputStream = new FileOutputStream(destinationFile);
- copyFile(inputStream, outputStream);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null)
- inputStream.close();
-
- if (outputStream != null)
- outputStream.close();
- }
- }
-
- private boolean cleanCacheIfNecessary(String pluginsPrefix, long packageVersion)
- {
- File versionFile = new File(pluginsPrefix + "cache.version");
-
- long cacheVersion = 0;
- if (versionFile.exists() && versionFile.canRead()) {
- DataInputStream inputStream = null;
- try {
- inputStream = new DataInputStream(new FileInputStream(versionFile));
- cacheVersion = inputStream.readLong();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- if (cacheVersion != packageVersion) {
- deleteRecursively(new File(pluginsPrefix));
- return true;
- } else {
- return false;
- }
- }
-
- private void extractBundledPluginsAndImports(String pluginsPrefix, String libsDir)
- throws IOException
- {
- long packageVersion = -1;
- try {
- PackageInfo packageInfo = m_context.getPackageManager().getPackageInfo(m_context.getPackageName(), 0);
- packageVersion = packageInfo.lastUpdateTime;
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- if (!cleanCacheIfNecessary(pluginsPrefix, packageVersion))
- return;
-
- {
- File versionFile = new File(pluginsPrefix + "cache.version");
-
- File parentDirectory = versionFile.getParentFile();
- if (!parentDirectory.exists())
- parentDirectory.mkdirs();
-
- versionFile.createNewFile();
-
- DataOutputStream outputStream = null;
- try {
- outputStream = new DataOutputStream(new FileOutputStream(versionFile));
- outputStream.writeLong(packageVersion);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (outputStream != null)
- outputStream.close();
- }
- }
-
- {
- // why can't we load the plugins directly from libs ?!?!
- String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY;
- if (m_contextInfo.metaData.containsKey(key)) {
- String[] list = m_context.getResources().getStringArray(m_contextInfo.metaData.getInt(key));
-
- for (String bundledImportBinary : list) {
- String[] split = bundledImportBinary.split(":");
- String sourceFileName = libsDir + split[0];
- String destinationFileName = pluginsPrefix + split[1];
- createBundledBinary(sourceFileName, destinationFileName);
- }
- }
- }
-
- {
- String key = BUNDLED_IN_ASSETS_RESOURCE_ID_KEY;
- if (m_contextInfo.metaData.containsKey(key)) {
- String[] list = m_context.getResources().getStringArray(m_contextInfo.metaData.getInt(key));
-
- for (String fileName : list) {
- String[] split = fileName.split(":");
- String sourceFileName = split[0];
- String destinationFileName = pluginsPrefix + split[1];
- copyAsset(sourceFileName, destinationFileName);
- }
- }
-
- }
- }
-
- private void deleteRecursively(File directory)
- {
- File[] files = directory.listFiles();
- if (files != null) {
- for (File file : files) {
- if (file.isDirectory())
- deleteRecursively(file);
- else
- file.delete();
- }
-
- directory.delete();
- }
- }
-
- private void cleanOldCacheIfNecessary(String oldLocalPrefix, String localPrefix)
- {
- File newCache = new File(localPrefix);
- if (!newCache.exists()) {
- {
- File oldPluginsCache = new File(oldLocalPrefix + "plugins/");
- if (oldPluginsCache.exists() && oldPluginsCache.isDirectory())
- deleteRecursively(oldPluginsCache);
- }
-
- {
- File oldImportsCache = new File(oldLocalPrefix + "imports/");
- if (oldImportsCache.exists() && oldImportsCache.isDirectory())
- deleteRecursively(oldImportsCache);
- }
-
- {
- File oldQmlCache = new File(oldLocalPrefix + "qml/");
- if (oldQmlCache.exists() && oldQmlCache.isDirectory())
- deleteRecursively(oldQmlCache);
- }
- }
- }
-
public void startApp(final boolean firstStart)
{
try {
@@ -553,7 +369,7 @@ public abstract class QtLoader {
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 = m_context.getResources().getStringArray(resourceId);
+ m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
}
if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs")
@@ -567,6 +383,7 @@ public abstract class QtLoader {
apkDeployFromSystem = true;
String libsDir = null;
+ String bundledLibsDir = null;
if (apkDeployFromSystem) {
String systemLibsPrefix = SYSTEM_LIB_PATH;
if (m_contextInfo.metaData.containsKey("android.app.system_libs_prefix")) {
@@ -583,8 +400,11 @@ public abstract class QtLoader {
} else {
String nativeLibraryPrefix = m_context.getApplicationInfo().nativeLibraryDir + "/";
File nativeLibraryDir = new File(nativeLibraryPrefix);
- if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0)
+ if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0) {
libsDir = nativeLibraryPrefix;
+ bundledLibsDir = nativeLibraryPrefix;
+ }
+
}
if (apkDeployFromSystem && libsDir == null)
@@ -593,33 +413,21 @@ public abstract class QtLoader {
if (m_qtLibs != null) {
String libPrefix = libsDir + "lib";
- for (int i = 0; i < m_qtLibs.length; i++)
- libraryList.add(libPrefix + m_qtLibs[i] + ".so");
+ for (String lib : m_qtLibs)
+ 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) {
- File dataDir = new File(m_context.getApplicationInfo().dataDir);
- String dataPath = dataDir.getCanonicalPath() + "/";
- String pluginsPrefix = dataPath + "qt-reserved-files/";
-
- if (libsDir == null)
- throw new Exception("");
-
- cleanOldCacheIfNecessary(dataPath, pluginsPrefix);
- extractBundledPluginsAndImports(pluginsPrefix, libsDir);
-
- if (m_contextInfo.metaData.containsKey(BUNDLED_IN_LIB_RESOURCE_ID_KEY)) {
- String[] extraLibs = m_contextInfo.metaData.getString("android.app.load_local_libs").split(":");
- for (String lib : extraLibs) {
+ int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id");
+ for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) {
+ for (String lib : libs.split(":")) {
if (!lib.isEmpty())
- libraryList.add(pluginsPrefix + lib);
+ libraryList.add(libsDir + lib);
}
}
-
- ENVIRONMENT_VARIABLES += "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
- + "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
- + "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins";
+ if (bundledLibsDir != null)
+ ENVIRONMENT_VARIABLES += "\tQT_BUNDLED_LIBS_PATH=" + bundledLibsDir;
}
Bundle loaderParams = new Bundle();
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index aed8a3c888..6d0f4e0d45 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -12,7 +12,7 @@
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
- <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
+ <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="-- %%INSERT_APP_NAME%% --"
@@ -34,12 +34,11 @@
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
- <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
- <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
+
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
- <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
+ <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Used to specify custom system library path to run with local system libs -->
diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle
index ed704c4957..3087d08c83 100644
--- a/src/android/templates/build.gradle
+++ b/src/android/templates/build.gradle
@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.0'
+ classpath 'com.android.tools.build:gradle:3.5.0'
}
}
@@ -44,7 +44,7 @@ android {
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qt5AndroidDir + '/res', 'res']
- resources.srcDirs = ['src']
+ resources.srcDirs = ['resources']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
@@ -54,4 +54,9 @@ android {
lintOptions {
abortOnError false
}
+
+ // Do not compress Qt binary resources file
+ aaptOptions {
+ noCompress 'rcc'
+ }
}
diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml
index 4009a7785a..6b1a4a2a02 100644
--- a/src/android/templates/res/values/libs.xml
+++ b/src/android/templates/res/values/libs.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
- <item>https://download.qt.io/ministro/android/qt5/qt-5.9</item>
+ <item>https://download.qt.io/ministro/android/qt5/qt-5.14</item>
</array>
<!-- The following is handled automatically by the deployment tool. It should
@@ -11,15 +11,12 @@
<!-- %%INSERT_EXTRA_LIBS%% -->
</array>
- <array name="qt_libs">
- <!-- %%INSERT_QT_LIBS%% -->
- </array>
-
- <array name="bundled_in_lib">
- <!-- %%INSERT_BUNDLED_IN_LIB%% -->
+ <array name="qt_libs">
+ <!-- %%INSERT_QT_LIBS%% -->
</array>
- <array name="bundled_in_assets">
- <!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
+
+ <array name="load_local_libs">
+ <!-- %%INSERT_LOCAL_LIBS%% -->
</array>
</resources>
diff --git a/src/android/templates/templates.pro b/src/android/templates/templates.pro
index 55387f3af7..9a64251ee3 100644
--- a/src/android/templates/templates.pro
+++ b/src/android/templates/templates.pro
@@ -1,3 +1,5 @@
+CONFIG += single_arch
+
CONFIG -= qt android_install
templates.files = \