From 7f7fd8ce96fd99a381483f2266d701076d6af73a Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Fri, 3 Nov 2023 00:24:43 +0200 Subject: [PATCH] Android: add missing extras native methods impls and registration This should have been done when the extras where moved to qtbase, it went under the rug and was forgotten. Pick-to: 6.5 6.2 Fixes: QTBUG-114971 Change-Id: Id7831a8bab8bedc1f869b9fc8bfc72acc3cca7a2 Reviewed-by: Volker Hilsheimer (cherry picked from commit 510cc564c07d41c2eb1689f1928c0b77f652ceb5) Reviewed-by: Assam Boudjelthia Reviewed-by: Qt CI Bot --- src/corelib/kernel/qjnihelpers.cpp | 9 ++-- src/corelib/kernel/qjnihelpers_p.h | 6 ++- .../platform/android/qandroidextras.cpp | 42 ++++++++++++++++++- .../android/qandroidnativeinterface.cpp | 4 +- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 78d05261e5b..ea3eaaaff24 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -3,7 +3,6 @@ #include "qjnihelpers_p.h" -#include "qjnienvironment.h" #include "qjniobject.h" #include "qlist.h" #include "qmutex.h" @@ -282,10 +281,14 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) if (!regOk && QJniEnvironment::checkAndClearExceptions(env)) return JNI_ERR; - if (!registerPermissionNatives()) + QJniEnvironment qJniEnv; + if (!registerPermissionNatives(qJniEnv)) return JNI_ERR; - if (!registerNativeInterfaceNatives()) + if (!registerNativeInterfaceNatives(qJniEnv)) + return JNI_ERR; + + if (!registerExtrasNatives(qJniEnv)) return JNI_ERR; return JNI_OK; diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index bce2b782de4..4e0b8a9b40f 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -19,6 +19,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -79,8 +80,9 @@ namespace QtAndroidPrivate jobject classLoader(); Q_CORE_EXPORT jint androidSdkVersion(); - bool registerPermissionNatives(); - bool registerNativeInterfaceNatives(); + bool registerPermissionNatives(QJniEnvironment &env); + bool registerNativeInterfaceNatives(QJniEnvironment &env); + bool registerExtrasNatives(QJniEnvironment &env); Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data); Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener); diff --git a/src/corelib/platform/android/qandroidextras.cpp b/src/corelib/platform/android/qandroidextras.cpp index 85f8a7e8089..13d4ff5566b 100644 --- a/src/corelib/platform/android/qandroidextras.cpp +++ b/src/corelib/platform/android/qandroidextras.cpp @@ -672,6 +672,45 @@ QAndroidBinder* QAndroidService::onBind(const QAndroidIntent &/*intent*/) return nullptr; } +static jboolean onTransact(JNIEnv */*env*/, jclass /*cls*/, jlong id, jint code, jobject data, + jobject reply, jint flags) +{ + if (!id) + return false; + + return reinterpret_cast(id)->onTransact( + code, QAndroidParcel(data), QAndroidParcel(reply), QAndroidBinder::CallType(flags)); +} + +static void onServiceConnected(JNIEnv */*env*/, jclass /*cls*/, jlong id, jstring name, + jobject service) +{ + if (!id) + return; + + return reinterpret_cast(id)->onServiceConnected( + QJniObject(name).toString(), QAndroidBinder(service)); +} + +static void onServiceDisconnected(JNIEnv */*env*/, jclass /*cls*/, jlong id, jstring name) +{ + if (!id) + return; + + return reinterpret_cast(id)->onServiceDisconnected( + QJniObject(name).toString()); +} + +bool QtAndroidPrivate::registerExtrasNatives(QJniEnvironment &env) +{ + static const JNINativeMethod methods[] = { + {"onTransact", "(JILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void *)onTransact}, + {"onServiceConnected", "(JLjava/lang/String;Landroid/os/IBinder;)V", (void *)onServiceConnected}, + {"onServiceDisconnected", "(JLjava/lang/String;)V", (void *)onServiceDisconnected} + }; + + return env.registerNativeMethods("org/qtproject/qt/android/extras/QtNative", methods, 3); +} /*! \class QAndroidIntent @@ -1171,7 +1210,7 @@ QtAndroidPrivate::checkPermission(const QString &permission) return QtFuture::makeReadyValueFuture(result); } -bool QtAndroidPrivate::registerPermissionNatives() +bool QtAndroidPrivate::registerPermissionNatives(QJniEnvironment &env) { if (QtAndroidPrivate::androidSdkVersion() < 23) return true; @@ -1181,7 +1220,6 @@ bool QtAndroidPrivate::registerPermissionNatives() reinterpret_cast(sendRequestPermissionsResult) }}; - QJniEnvironment env; return env.registerNativeMethods(qtNativeClassName, methods, 1); } diff --git a/src/corelib/platform/android/qandroidnativeinterface.cpp b/src/corelib/platform/android/qandroidnativeinterface.cpp index 5b967f22bf0..9bbceff6171 100644 --- a/src/corelib/platform/android/qandroidnativeinterface.cpp +++ b/src/corelib/platform/android/qandroidnativeinterface.cpp @@ -231,11 +231,11 @@ static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/) } #endif -bool QtAndroidPrivate::registerNativeInterfaceNatives() +bool QtAndroidPrivate::registerNativeInterfaceNatives(QJniEnvironment &env) { #if QT_CONFIG(future) && !defined(QT_NO_QOBJECT) const JNINativeMethod methods = {"runPendingCppRunnables", "()V", (void *)runPendingCppRunnables}; - return QJniEnvironment().registerNativeMethods(qtNativeClassName, &methods, 1); + return env.registerNativeMethods(qtNativeClassName, &methods, 1); #else return true; #endif