diff options
| author | Soheil Armin <[email protected]> | 2024-05-13 01:44:22 +0300 |
|---|---|---|
| committer | Soheil Armin <[email protected]> | 2024-05-22 15:54:01 +0300 |
| commit | 5b0284e8ee757536554ccd73e07c79028c754372 (patch) | |
| tree | e845bf381cb4b6bc3a30d7ac2012a15482426a77 | |
| parent | 9166e9ffb62a16ed94743a9080772e8f27ba0299 (diff) | |
Android: Move Java types and conversion functions to their own header
Task-number: QTBUG-125291
Change-Id: Ia675c97c296fa1aad1a06b4c4de23b2f803ede7f
Reviewed-by: Assam Boudjelthia <[email protected]>
| -rw-r--r-- | src/quick/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidquickviewembedding.cpp | 62 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidtypeconverter_p.h | 77 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidtypes_p.h | 33 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidviewsignalmanager.cpp | 33 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidviewsignalmanager_p.h | 6 |
6 files changed, 131 insertions, 82 deletions
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index f83a400c59..e8b9345293 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -563,6 +563,8 @@ qt_internal_extend_target(Quick CONDITION ANDROID SOURCES platform/android/qandroidquickviewembedding.cpp platform/android/qandroidquickviewembedding_p.h platform/android/qandroidviewsignalmanager.cpp platform/android/qandroidviewsignalmanager_p.h + platform/android/qandroidtypes_p.h + platform/android/qandroidtypeconverter_p.h ) if (ANDROID) add_subdirectory(jar) diff --git a/src/quick/platform/android/qandroidquickviewembedding.cpp b/src/quick/platform/android/qandroidquickviewembedding.cpp index 925120bc09..6308fc02f0 100644 --- a/src/quick/platform/android/qandroidquickviewembedding.cpp +++ b/src/quick/platform/android/qandroidquickviewembedding.cpp @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <QtQuick/private/qandroidquickviewembedding_p.h> +#include <QtQuick/private/qandroidtypes_p.h> +#include <QtQuick/private/qandroidtypeconverter_p.h> #include <QtQuick/private/qandroidviewsignalmanager_p.h> #include <QtCore/qcoreapplication.h> @@ -19,14 +21,6 @@ Q_DECLARE_JNI_CLASS(QtQuickView, "org/qtproject/qt/android/QtQuickView"); Q_DECLARE_JNI_CLASS(QtWindow, "org/qtproject/qt/android/QtWindow"); Q_DECLARE_JNI_CLASS(View, "android/view/View"); -Q_DECLARE_JNI_CLASS(Void, "java/lang/Void"); -Q_DECLARE_JNI_CLASS(Integer, "java/lang/Integer"); -Q_DECLARE_JNI_CLASS(Double, "java/lang/Double"); -Q_DECLARE_JNI_CLASS(Float, "java/lang/Float"); -Q_DECLARE_JNI_CLASS(Boolean, "java/lang/Boolean"); -Q_DECLARE_JNI_CLASS(String, "java/lang/String"); -Q_DECLARE_JNI_CLASS(Class, "java/lang/Class"); - namespace QtAndroidQuickViewEmbedding { constexpr const char *uninitializedViewMessage = "because QtQuickView is not loaded or ready yet."; @@ -105,20 +99,14 @@ namespace QtAndroidQuickViewEmbedding QMetaProperty metaProperty = rootMetaObject->property(propertyIndex); const QJniObject propertyValue(value); - const QByteArray valueClassname = propertyValue.className(); - - if (valueClassname == QtJniTypes::Traits<QtJniTypes::String>::className()) - metaProperty.write(rootObject, propertyValue.toString()); - else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Integer>::className()) - metaProperty.write(rootObject, propertyValue.callMethod<jint>("intValue")); - else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Double>::className()) - metaProperty.write(rootObject, propertyValue.callMethod<jdouble>("doubleValue")); - else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Float>::className()) - metaProperty.write(rootObject, propertyValue.callMethod<jfloat>("floatValue")); - else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Boolean>::className()) - metaProperty.write(rootObject, propertyValue.callMethod<jboolean>("booleanValue")); - else - qWarning("Setting the property type of %s is not supported.", valueClassname.data()); + const QVariant variantToWrite = QAndroidTypeConverter::toQVariant(propertyValue); + + if (!variantToWrite.isValid()) { + qWarning("Setting the property type of %s is not supported.", + qPrintable(propertyValue.className())); + } else { + metaProperty.write(rootObject, variantToWrite); + } } jobject getRootObjectProperty(JNIEnv *env, jobject object, jlong windowReference, @@ -143,35 +131,13 @@ namespace QtAndroidQuickViewEmbedding } QMetaProperty metaProperty = rootMetaObject->property(propertyIndex); - QVariant propertyValue = metaProperty.read(rootObject); - const int propertyTypeId = propertyValue.typeId(); - - switch (propertyTypeId) { - case QMetaType::Type::Int: - return env->NewLocalRef( - QJniObject::construct<QtJniTypes::Integer>(get<int>(std::move(propertyValue))) - .object()); - case QMetaType::Type::Double: - return env->NewLocalRef( - QJniObject::construct<QtJniTypes::Double>(get<double>(std::move(propertyValue))) - .object()); - case QMetaType::Type::Float: - return env->NewLocalRef( - QJniObject::construct<QtJniTypes::Float>(get<float>(std::move(propertyValue))) - .object()); - case QMetaType::Type::Bool: - return env->NewLocalRef( - QJniObject::construct<QtJniTypes::Boolean>(get<bool>(std::move(propertyValue))) - .object()); - case QMetaType::Type::QString: - return env->NewLocalRef( - QJniObject::fromString(get<QString>(std::move(propertyValue))).object()); - default: + const QVariant propertyValue = metaProperty.read(rootObject); + jobject jObject = QAndroidTypeConverter::toJavaObject(propertyValue, env); + if (!jObject) { qWarning("Property %s cannot be converted to a supported Java data type.", qPrintable(property)); } - - return nullptr; + return jObject; } int addRootObjectSignalListener(JNIEnv *env, jobject, jlong windowReference, jstring signalName, diff --git a/src/quick/platform/android/qandroidtypeconverter_p.h b/src/quick/platform/android/qandroidtypeconverter_p.h new file mode 100644 index 0000000000..b2274507fd --- /dev/null +++ b/src/quick/platform/android/qandroidtypeconverter_p.h @@ -0,0 +1,77 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QANDROIDTYPECONVERTER_P_H +#define QANDROIDTYPECONVERTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include <QtQuick/private/qandroidtypes_p.h> + +#include <QtCore/qjniobject.h> +#include <QtCore/qjnienvironment.h> +#include <QtCore/qjnitypes.h> + +QT_BEGIN_NAMESPACE + +namespace QAndroidTypeConverter +{ + [[maybe_unused]] static QVariant toQVariant(const QJniObject &object) + { + if (!object.isValid()) + return QVariant{}; + const QByteArray classname(object.className()); + + if (classname == QtJniTypes::Traits<QtJniTypes::String>::className()) + return object.toString(); + else if (classname == QtJniTypes::Traits<QtJniTypes::Integer>::className()) + return object.callMethod<jint>("intValue"); + else if (classname == QtJniTypes::Traits<QtJniTypes::Double>::className()) + return object.callMethod<jdouble>("doubleValue"); + else if (classname == QtJniTypes::Traits<QtJniTypes::Float>::className()) + return object.callMethod<jfloat>("floatValue"); + else if (classname == QtJniTypes::Traits<QtJniTypes::Boolean>::className()) + return object.callMethod<jboolean>("booleanValue"); + + return QVariant{}; + } + + [[maybe_unused]] Q_REQUIRED_RESULT static jobject toJavaObject(const QVariant &var, JNIEnv *env) + { + Q_ASSERT(env); + switch (var.typeId()) { + case QMetaType::Type::Int: + return env->NewLocalRef(QJniObject::construct<QtJniTypes::Integer>( + get<int>(var)) + .object()); + case QMetaType::Type::Double: + return env->NewLocalRef(QJniObject::construct<QtJniTypes::Double>( + get<double>(var)) + .object()); + case QMetaType::Type::Float: + return env->NewLocalRef(QJniObject::construct<QtJniTypes::Float>( + get<float>(var)) + .object()); + case QMetaType::Type::Bool: + return env->NewLocalRef(QJniObject::construct<QtJniTypes::Boolean>( + get<bool>(var)) + .object()); + case QMetaType::Type::QString: + return env->NewLocalRef( + QJniObject::fromString(get<QString>(var)).object()); + } + return nullptr; + } +}; + +QT_END_NAMESPACE + +#endif // QANDROIDTYPECONVERTER_P_H diff --git a/src/quick/platform/android/qandroidtypes_p.h b/src/quick/platform/android/qandroidtypes_p.h new file mode 100644 index 0000000000..2bbb40de4d --- /dev/null +++ b/src/quick/platform/android/qandroidtypes_p.h @@ -0,0 +1,33 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QANDROIDTYPES_P_H +#define QANDROIDTYPES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include <QtCore/qjniobject.h> +#include <QtCore/qjnienvironment.h> +#include <QtCore/qjnitypes.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_JNI_CLASS(Void, "java/lang/Void"); +Q_DECLARE_JNI_CLASS(Integer, "java/lang/Integer"); +Q_DECLARE_JNI_CLASS(Double, "java/lang/Double"); +Q_DECLARE_JNI_CLASS(Float, "java/lang/Float"); +Q_DECLARE_JNI_CLASS(Boolean, "java/lang/Boolean"); +Q_DECLARE_JNI_CLASS(String, "java/lang/String"); +Q_DECLARE_JNI_CLASS(Class, "java/lang/Class"); + +QT_END_NAMESPACE + +#endif // QANDROIDTYPES_P_H diff --git a/src/quick/platform/android/qandroidviewsignalmanager.cpp b/src/quick/platform/android/qandroidviewsignalmanager.cpp index 60599aae3d..9fb5fc4ec5 100644 --- a/src/quick/platform/android/qandroidviewsignalmanager.cpp +++ b/src/quick/platform/android/qandroidviewsignalmanager.cpp @@ -1,16 +1,11 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include <QtQuick/private/qandroidtypeconverter_p.h> #include <QtQuick/private/qandroidviewsignalmanager_p.h> QT_BEGIN_NAMESPACE -Q_DECLARE_JNI_CLASS(Void, "java/lang/Void"); -Q_DECLARE_JNI_CLASS(Integer, "java/lang/Integer"); -Q_DECLARE_JNI_CLASS(Double, "java/lang/Double"); -Q_DECLARE_JNI_CLASS(Float, "java/lang/Float"); -Q_DECLARE_JNI_CLASS(Boolean, "java/lang/Boolean"); - void QAndroidViewSignalManager::forwardSignal() { invokeListener(sender(), senderSignalIndex(), QVariant()); @@ -61,28 +56,10 @@ void QAndroidViewSignalManager::invokeListener(QObject *sender, int senderSignal if (connectionInfo.propertyIndex != -1 && javaArgType != Traits<Void>::className()) signalValue = metaObject->property(connectionInfo.propertyIndex).read(sender); - int valueTypeId = signalValue.typeId(); - QJniObject jValue; - - switch (valueTypeId) { - case QMetaType::Type::UnknownType: - break; - case QMetaType::Type::Int: - jValue = qVariantToJniObject<Integer, jint>(signalValue); - break; - case QMetaType::Type::Double: - jValue = qVariantToJniObject<Double, jdouble>(signalValue); - break; - case QMetaType::Type::Float: - jValue = qVariantToJniObject<Float, jfloat>(signalValue); - break; - case QMetaType::Type::Bool: - jValue = qVariantToJniObject<Boolean, jboolean>(signalValue); - break; - case QMetaType::Type::QString: - jValue = QJniObject::fromString(get<QString>(std::move(signalValue))); - break; - default: + QJniObject jValue( + QAndroidTypeConverter::toJavaObject(signalValue, QJniEnvironment::getJniEnv())); + + if (!jValue.isValid()) { qWarning("Mismatching argument types between QML signal (%s) and the Java function " "(%s). Sending null as argument.", signalMethod.methodSignature().constData(), javaArgType.constData()); diff --git a/src/quick/platform/android/qandroidviewsignalmanager_p.h b/src/quick/platform/android/qandroidviewsignalmanager_p.h index 54a732a57a..c6ca6543b3 100644 --- a/src/quick/platform/android/qandroidviewsignalmanager_p.h +++ b/src/quick/platform/android/qandroidviewsignalmanager_p.h @@ -43,12 +43,6 @@ public: QMultiMap<QByteArray, ConnectionInfo> connectionInfoMap; QHash<int, QMetaObject::Connection> connections; - template <typename JT, typename T> - inline QJniObject qVariantToJniObject(const QVariant &v) - { - return QJniObject(QtJniTypes::Traits<JT>::className(), get<T>(std::move(v))); - }; - public slots: void forwardSignal(); void forwardSignal(int); |
