diff options
Diffstat (limited to 'src/corelib/plugin/qlibrary_unix.cpp')
-rw-r--r-- | src/corelib/plugin/qlibrary_unix.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index e03814984c..f0de1010d7 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -52,6 +52,10 @@ # include <private/qcore_mac_p.h> #endif +#ifdef Q_OS_ANDROID +# include <private/qjnihelpers_p.h> +#endif + QT_BEGIN_NAMESPACE static QString qdlerror() @@ -77,14 +81,14 @@ QStringList QLibraryPrivate::suffixes_sys(const QString& fullVersion) // .so is preferred. # if defined(__ia64) if (!fullVersion.isEmpty()) { - suffixes << QString::fromLatin1(".so.%1").arg(fullVersion); + suffixes << QLatin1String(".so.%1").arg(fullVersion); } else { suffixes << QLatin1String(".so"); } # endif if (!fullVersion.isEmpty()) { - suffixes << QString::fromLatin1(".sl.%1").arg(fullVersion); - suffixes << QString::fromLatin1(".%1").arg(fullVersion); + suffixes << QLatin1String(".sl.%1").arg(fullVersion); + suffixes << QLatin1String(".%1").arg(fullVersion); } else { suffixes << QLatin1String(".sl"); } @@ -93,15 +97,18 @@ QStringList QLibraryPrivate::suffixes_sys(const QString& fullVersion) #else if (!fullVersion.isEmpty()) { - suffixes << QString::fromLatin1(".so.%1").arg(fullVersion); + suffixes << QLatin1String(".so.%1").arg(fullVersion); } else { suffixes << QLatin1String(".so"); +# ifdef Q_OS_ANDROID + suffixes << QStringLiteral(LIBS_SUFFIX); +# endif } #endif # ifdef Q_OS_MAC if (!fullVersion.isEmpty()) { - suffixes << QString::fromLatin1(".%1.bundle").arg(fullVersion); - suffixes << QString::fromLatin1(".%1.dylib").arg(fullVersion); + suffixes << QLatin1String(".%1.bundle").arg(fullVersion); + suffixes << QLatin1String(".%1.dylib").arg(fullVersion); } else { suffixes << QLatin1String(".bundle") << QLatin1String(".dylib"); } @@ -157,9 +164,12 @@ bool QLibraryPrivate::load_sys() // Do not unload the library during dlclose(). Consequently, the // library's specific static variables are not reinitialized if the // library is reloaded with dlopen() at a later time. -#if defined(RTLD_NODELETE) && !defined(Q_OS_ANDROID) +#if defined(RTLD_NODELETE) if (loadHints & QLibrary::PreventUnloadHint) { - dlFlags |= RTLD_NODELETE; +# ifdef Q_OS_ANDROID // RTLD_NODELETE flag is supported by Android 23+ + if (QtAndroidPrivate::androidSdkVersion() > 22) +# endif + dlFlags |= RTLD_NODELETE; } #endif @@ -219,7 +229,22 @@ bool QLibraryPrivate::load_sys() } else { attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix); } + pHnd = dlopen(QFile::encodeName(attempt), dlFlags); +#ifdef Q_OS_ANDROID + if (!pHnd) { + auto attemptFromBundle = attempt; + pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags); + } + if (pHnd) { + using JniOnLoadPtr = jint (*)(JavaVM *vm, void *reserved); + JniOnLoadPtr jniOnLoad = reinterpret_cast<JniOnLoadPtr>(dlsym(pHnd, "JNI_OnLoad")); + if (jniOnLoad && jniOnLoad(QtAndroidPrivate::javaVM(), nullptr) == JNI_ERR) { + dlclose(pHnd); + pHnd = nullptr; + } + } +#endif if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) { // We only want to continue if dlopen failed due to that the shared library did not exist. |