diff options
Diffstat (limited to 'tests/auto/corelib/kernel/qjnienvironment')
3 files changed, 148 insertions, 7 deletions
diff --git a/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt b/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt index 25e7e51ba6..f405438314 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt @@ -1,7 +1,16 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + ##################################################################### ## tst_qjnienvironment Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qjnienvironment LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qjnienvironment SOURCES tst_qjnienvironment.cpp @@ -11,6 +20,4 @@ if(ANDROID) set_property(TARGET tst_qjnienvironment APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/testdata ) - # QTBUG-88840 - qt_android_generate_deployment_settings(tst_qjnienvironment) endif() diff --git a/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java b/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java index 0fc70f2567..4f307b3bc7 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java +++ b/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java @@ -1,11 +1,15 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only package org.qtproject.qt.android.testdatapackage; public class QtJniEnvironmentTestClass { private static native void callbackFromJava(String message); + private static native void namedCallbackFromJava(String message); + private static native void memberCallbackFromJava(String message); + private static native void namedMemberCallbackFromJava(String message); + private static native void namespaceCallbackFromJava(String message); private static native void intCallbackFromJava(int value); public final int INT_FIELD = 123; @@ -18,6 +22,26 @@ public class QtJniEnvironmentTestClass callbackFromJava("From Java: " + message); } + public static void namedAppendJavaToString(String message) + { + namedCallbackFromJava("From Java (named): " + message); + } + + public static void memberAppendJavaToString(String message) + { + memberCallbackFromJava("From Java (member): " + message); + } + + public static void namedMemberAppendJavaToString(String message) + { + namedMemberCallbackFromJava("From Java (named member): " + message); + } + + public static void namespaceAppendJavaToString(String message) + { + namespaceCallbackFromJava("From Java (namespace): " + message); + } + public static void convertToInt(String message) { intCallbackFromJava(Integer.parseInt(message)); diff --git a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp index f699d6816a..95748f46f7 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp +++ b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <jni.h> @@ -20,6 +20,7 @@ class tst_QJniEnvironment : public QObject Q_OBJECT private slots: + void init(); void jniEnv(); void javaVM(); void registerNativeMethods(); @@ -30,6 +31,14 @@ private slots: void findStaticField(); }; +void tst_QJniEnvironment::init() +{ + // Unless explicitly ignored to test error handling, warning messages + // in this test about a failure to look up a field, method, or class + // make the test fail. + QTest::failOnWarning(QRegularExpression("java.lang.NoSuch.*Error")); +} + void tst_QJniEnvironment::jniEnv() { QJniEnvironment env; @@ -59,17 +68,21 @@ void tst_QJniEnvironment::jniEnv() QVERIFY(!QJniEnvironment::checkAndClearExceptions(env.jniEnv())); // try to find a nonexistent class + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*")); QVERIFY(!env->FindClass("this/doesnt/Exist")); QVERIFY(QJniEnvironment::checkAndClearExceptions(env.jniEnv())); // try to find an existing class with QJniEnvironment QJniEnvironment env; QVERIFY(env.findClass("java/lang/Object")); + QVERIFY(env.findClass<jstring>()); // try to find a nonexistent class + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*")); QVERIFY(!env.findClass("this/doesnt/Exist")); // clear exception with member function + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*")); QVERIFY(!env->FindClass("this/doesnt/Exist")); QVERIFY(env.checkAndClearExceptions()); } @@ -98,14 +111,49 @@ static void callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) Q_UNUSED(env) registerNativesString = QJniObject(value).toString(); } -Q_JNI_DECLARE_NATIVE_METHOD(callbackFromJava); +Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJava); + +static void tediouslyLongNamed_callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) +{ + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); +} +Q_DECLARE_JNI_NATIVE_METHOD(tediouslyLongNamed_callbackFromJava, namedCallbackFromJava) static void callbackFromJavaNoCtor(JNIEnv *env, jobject /*thiz*/, jstring value) { Q_UNUSED(env) registerNativesString = QJniObject(value).toString(); } -Q_JNI_DECLARE_NATIVE_METHOD(callbackFromJavaNoCtor); +Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJavaNoCtor); + +class CallbackClass { +public: + static void memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(memberCallbackFromJava) + + static void tediouslyLongNamed_memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, + jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(tediouslyLongNamed_memberCallbackFromJava, + namedMemberCallbackFromJava) +}; + +namespace CallbackNamespace { + static void namespaceCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(namespaceCallbackFromJava) +} void tst_QJniEnvironment::registerNativeMethods() { @@ -125,6 +173,63 @@ void tst_QJniEnvironment::registerNativeMethods() QVERIFY(registerNativesString == QStringLiteral("From Java: Qt")); } + // Named native function + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_METHOD(tediouslyLongNamed_callbackFromJava) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namedAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (named): Qt")); + } + + // Static class member as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(memberCallbackFromJava, CallbackClass) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "memberAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (member): Qt")); + } + + // Static named class member as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(tediouslyLongNamed_memberCallbackFromJava, + CallbackClass) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namedMemberAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (named member): Qt")); + } + + // Function generally just in namespace as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(namespaceCallbackFromJava, CallbackNamespace) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namespaceAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (namespace): Qt")); + } + // No default constructor in class { QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, { @@ -145,7 +250,7 @@ static void intCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jint value) Q_UNUSED(env) registerNativeInteger = static_cast<int>(value); } -Q_JNI_DECLARE_NATIVE_METHOD(intCallbackFromJava); +Q_DECLARE_JNI_NATIVE_METHOD(intCallbackFromJava); void tst_QJniEnvironment::registerNativeMethodsByJclass() { @@ -180,6 +285,7 @@ void tst_QJniEnvironment::findMethod() QVERIFY(methodId != nullptr); // invalid signature + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*")); jmethodID invalid = env.findMethod(clazz, "unknown", "()I"); QVERIFY(invalid == nullptr); // check that all exceptions are already cleared @@ -206,8 +312,10 @@ void tst_QJniEnvironment::findStaticMethod() QCOMPARE(result, 123); // invalid method + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*")); jmethodID invalid = env.findStaticMethod(clazz, "unknown", "()I"); QVERIFY(invalid == nullptr); + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*")); invalid = env.findStaticMethod<jint>(clazz, "unknown"); QVERIFY(invalid == nullptr); // check that all exceptions are already cleared @@ -235,6 +343,7 @@ void tst_QJniEnvironment::findField() QVERIFY(value == 123); // invalid signature + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchFieldError: .*")); jfieldID invalidId = env.findField(clazz, "unknown", "I"); QVERIFY(invalidId == nullptr); // check that all exceptions are already cleared @@ -258,6 +367,7 @@ void tst_QJniEnvironment::findStaticField() QVERIFY(size == 321); // invalid signature + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchFieldError: .*")); jfieldID invalidId = env.findStaticField(clazz, "unknown", "I"); QVERIFY(invalidId == nullptr); // check that all exceptions are already cleared |