aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoheil Armin <[email protected]>2024-04-20 16:16:01 +0300
committerSoheil Armin <[email protected]>2024-05-22 15:53:55 +0300
commit1163e6a420968508b67e803c3e1f197d5b97cc52 (patch)
treebddf3dd931d0d9dee97e3bcbed9354919c6071ef
parent7d2e12243f7d418a9bf52673c393fc60ed1b4365 (diff)
Android: Rename and split SignalHelper into new header and source files
SignalHelper renamed to QAndroidViewSignalManger SignalInfo nested struct renamed to ConnectionInfo And QAndroidViewSignalManger split into new header and source files. Task-number: QTBUG-124488 Change-Id: I77ab8bf995043993224a6c5cafce5ac57dca59d9 Reviewed-by: Assam Boudjelthia <[email protected]>
-rw-r--r--src/quick/CMakeLists.txt1
-rw-r--r--src/quick/platform/android/qandroidquickviewembedding.cpp154
-rw-r--r--src/quick/platform/android/qandroidquickviewembedding_p.h34
-rw-r--r--src/quick/platform/android/qandroidviewsignalmanager.cpp100
-rw-r--r--src/quick/platform/android/qandroidviewsignalmanager_p.h64
5 files changed, 201 insertions, 152 deletions
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt
index ce0322f4ce..f83a400c59 100644
--- a/src/quick/CMakeLists.txt
+++ b/src/quick/CMakeLists.txt
@@ -562,6 +562,7 @@ qt_internal_extend_target(Quick CONDITION QT_FEATURE_metal
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
)
if (ANDROID)
add_subdirectory(jar)
diff --git a/src/quick/platform/android/qandroidquickviewembedding.cpp b/src/quick/platform/android/qandroidquickviewembedding.cpp
index dbe6c69767..f6d4f04b22 100644
--- a/src/quick/platform/android/qandroidquickviewembedding.cpp
+++ b/src/quick/platform/android/qandroidquickviewembedding.cpp
@@ -2,6 +2,7 @@
// 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/qandroidviewsignalmanager_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qjnienvironment.h>
@@ -54,7 +55,7 @@ namespace QtAndroidQuickViewEmbedding
QWindow *parentWindow = reinterpret_cast<QWindow *>(parentWindowReference);
QQuickView *view = new QQuickView(parentWindow);
QQmlEngine *engine = view->engine();
- new SignalHelper(view);
+ new QAndroidViewSignalManager(view);
QObject::connect(view, &QQuickView::statusChanged,
[qtViewObject](QQuickView::Status status) {
qtViewObject.callMethod<void>("handleStatusChange", status);
@@ -194,7 +195,7 @@ namespace QtAndroidQuickViewEmbedding
return -1;
}
- SignalHelper *signalHelper = view->findChild<SignalHelper *>();
+ QAndroidViewSignalManager *signalManager = view->findChild<QAndroidViewSignalManager *>();
const QByteArray javaArgClass = QJniObject(argType).className();
const char *qArgName =
QMetaType(javaToQMetaType.value(javaArgClass, QMetaType::Type::UnknownType)).name();
@@ -233,7 +234,7 @@ namespace QtAndroidQuickViewEmbedding
if (signalIndex == -1)
return -1;
- const QMetaObject *helperMetaObject = signalHelper->metaObject();
+ const QMetaObject *helperMetaObject = signalManager->metaObject();
QByteArray helperSignalSignature = signalSignature;
helperSignalSignature.replace(0, signalSignature.indexOf('('), "forwardSignal");
int helperSlotIndex = helperMetaObject->indexOfSlot(helperSignalSignature.constData());
@@ -242,15 +243,17 @@ namespace QtAndroidQuickViewEmbedding
// Return the id if the signal is already connected to the same listener.
QJniObject listenerJniObject(listener);
- if (signalHelper->listenersMap.contains(signalSignature)) {
- auto listenerInfos = signalHelper->listenersMap.values(signalSignature);
- auto isSameListener = [listenerJniObject](const SignalHelper::ListenerInfo &listenerInfo) {
- return listenerInfo.listener == listenerJniObject;
- };
- auto iterator = std::find_if(listenerInfos.constBegin(),
- listenerInfos.constEnd(),
+ if (signalManager->connectionInfoMap.contains(signalSignature)) {
+ auto connectionInfos = signalManager->connectionInfoMap.values(signalSignature);
+ auto isSameListener =
+ [listenerJniObject](
+ const QAndroidViewSignalManager::ConnectionInfo &connectionInfo) {
+ return connectionInfo.listener == listenerJniObject;
+ };
+ auto iterator = std::find_if(connectionInfos.constBegin(),
+ connectionInfos.constEnd(),
isSameListener);
- if (iterator != listenerInfos.end()) {
+ if (iterator != connectionInfos.end()) {
qWarning("Signal listener with the ID of %i is already connected to %s signal.",
iterator->id,
signalSignature.constData());
@@ -260,30 +263,30 @@ namespace QtAndroidQuickViewEmbedding
QMetaMethod signalMethod = metaObject->method(signalIndex);
QMetaMethod signalForwarderMethod = helperMetaObject->method(helperSlotIndex);
- signalHelper->connectionHandleCounter++;
+ signalManager->connectionHandleCounter++;
QMetaObject::Connection connection;
- if (signalHelper->listenersMap.contains(signalSignature)) {
- connection = signalHelper
- ->connections[signalHelper->listenersMap.value(signalSignature).id];
+ if (signalManager->connectionInfoMap.contains(signalSignature)) {
+ const int existingId = signalManager->connectionInfoMap.value(signalSignature).id;
+ connection = signalManager->connections[existingId];
} else {
connection = QObject::connect(rootObject,
signalMethod,
- signalHelper,
+ signalManager,
signalForwarderMethod);
}
- SignalHelper::ListenerInfo listenerInfo;
- listenerInfo.listener = listenerJniObject;
- listenerInfo.javaArgType = javaArgClass;
- listenerInfo.propertyIndex = propertyIndex;
- listenerInfo.signalSignature = signalSignature;
- listenerInfo.id = signalHelper->connectionHandleCounter;
+ QAndroidViewSignalManager::ConnectionInfo connectionInfo;
+ connectionInfo.listener = listenerJniObject;
+ connectionInfo.javaArgType = javaArgClass;
+ connectionInfo.propertyIndex = propertyIndex;
+ connectionInfo.signalSignature = signalSignature;
+ connectionInfo.id = signalManager->connectionHandleCounter;
- signalHelper->listenersMap.insert(signalSignature, listenerInfo);
- signalHelper->connections.insert(listenerInfo.id, connection);
+ signalManager->connectionInfoMap.insert(signalSignature, connectionInfo);
+ signalManager->connections.insert(connectionInfo.id, connection);
- return listenerInfo.id;
+ return connectionInfo.id;
}
bool removeRootObjectSignalListener(JNIEnv *, jobject, jlong windowReference,
@@ -296,16 +299,16 @@ namespace QtAndroidQuickViewEmbedding
return false;
}
- SignalHelper *signalHelper = view->findChild<SignalHelper *>();
- if (!signalHelper->connections.contains(signalListenerId))
+ QAndroidViewSignalManager *signalManager = view->findChild<QAndroidViewSignalManager *>();
+ if (!signalManager->connections.contains(signalListenerId))
return false;
QByteArray signalSignature;
- for (auto listenerInfoIter = signalHelper->listenersMap.begin();
- listenerInfoIter != signalHelper->listenersMap.end();) {
+ for (auto listenerInfoIter = signalManager->connectionInfoMap.begin();
+ listenerInfoIter != signalManager->connectionInfoMap.end();) {
if (listenerInfoIter->id == signalListenerId) {
signalSignature = listenerInfoIter->signalSignature;
- signalHelper->listenersMap.erase(listenerInfoIter);
+ signalManager->connectionInfoMap.erase(listenerInfoIter);
break;
} else {
++listenerInfoIter;
@@ -313,98 +316,13 @@ namespace QtAndroidQuickViewEmbedding
}
// disconnect if its the last listener associated with the signal signatures
- if (!signalHelper->listenersMap.contains(signalSignature))
- rootObject->disconnect(signalHelper->connections.value(signalListenerId));
+ if (!signalManager->connectionInfoMap.contains(signalSignature))
+ rootObject->disconnect(signalManager->connections.value(signalListenerId));
- signalHelper->connections.remove(signalListenerId);
+ signalManager->connections.remove(signalListenerId);
return true;
}
- void SignalHelper::forwardSignal()
- {
- invokeListener(sender(), senderSignalIndex(), QVariant());
- }
-
- void SignalHelper::forwardSignal(int signalValue)
- {
- invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
- }
-
- void SignalHelper::forwardSignal(bool signalValue)
- {
- invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
- }
-
- void SignalHelper::forwardSignal(double signalValue)
- {
- invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
- }
-
- void SignalHelper::forwardSignal(float signalValue)
- {
- invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
- }
-
- void SignalHelper::forwardSignal(QString signalValue)
- {
- invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
- }
-
- void SignalHelper::invokeListener(QObject *sender, int senderSignalIndex, QVariant signalValue)
- {
- using namespace QtJniTypes;
-
- const QMetaObject *metaObject = sender->metaObject();
- const QMetaMethod signalMethod = metaObject->method(senderSignalIndex);
-
- for (auto listenerInfoIter = listenersMap.constFind(signalMethod.methodSignature());
- listenerInfoIter != listenersMap.constEnd() &&
- listenerInfoIter.key() == signalMethod.methodSignature();
- ++listenerInfoIter) {
- const ListenerInfo listenerInfo = *listenerInfoIter;
- const QByteArray javaArgType = listenerInfo.javaArgType;
- QJniObject jSignalMethodName =
- QJniObject::fromString(QLatin1StringView(signalMethod.name()));
-
- if (listenerInfo.propertyIndex != -1 && javaArgType != Traits<Void>::className())
- signalValue = metaObject->property(listenerInfo.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:
- qWarning("Mismatching argument types between QML signal (%s) and the Java function "
- "(%s). Sending null as argument.",
- signalMethod.methodSignature().constData(), javaArgType.constData());
- }
-
- QNativeInterface::QAndroidApplication::runOnAndroidMainThread(
- [listenerInfo, jSignalMethodName, jValue]() {
- listenerInfo.listener.callMethod<void, jstring, jobject>("onSignalEmitted",
- jSignalMethodName.object<jstring>(),
- jValue.object());
- });
- }
- }
-
bool registerNatives(QJniEnvironment& env) {
return env.registerNativeMethods(QtJniTypes::Traits<QtJniTypes::QtQuickView>::className(),
{Q_JNI_NATIVE_SCOPED_METHOD(createQuickView,
diff --git a/src/quick/platform/android/qandroidquickviewembedding_p.h b/src/quick/platform/android/qandroidquickviewembedding_p.h
index ace387a7f1..c20585c5d0 100644
--- a/src/quick/platform/android/qandroidquickviewembedding_p.h
+++ b/src/quick/platform/android/qandroidquickviewembedding_p.h
@@ -41,40 +41,6 @@ namespace QtAndroidQuickViewEmbedding
bool removeRootObjectSignalListener(JNIEnv *env, jobject, jlong parentWindowReference,
jint signalListenerId);
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(removeRootObjectSignalListener)
-
- class SignalHelper : public QObject
- {
- Q_OBJECT
- public:
- struct ListenerInfo
- {
- ListenerInfo() : propertyIndex(-1) { }
- int id;
- QJniObject listener;
- QByteArray javaArgType;
- QByteArray signalSignature;
- int propertyIndex;
- };
-
- int connectionHandleCounter;
- explicit SignalHelper(QQuickView *parent) : QObject(parent), connectionHandleCounter(0) { }
- QMultiMap<QByteArray, ListenerInfo> listenersMap;
- QHash<int, QMetaObject::Connection> connections;
- void invokeListener(QObject *sender, int senderSignalIndex, QVariant signalValue);
-
- 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);
- void forwardSignal(double);
- void forwardSignal(float);
- void forwardSignal(bool);
- void forwardSignal(QString);
- };
};
QT_END_NAMESPACE
diff --git a/src/quick/platform/android/qandroidviewsignalmanager.cpp b/src/quick/platform/android/qandroidviewsignalmanager.cpp
new file mode 100644
index 0000000000..60599aae3d
--- /dev/null
+++ b/src/quick/platform/android/qandroidviewsignalmanager.cpp
@@ -0,0 +1,100 @@
+// 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/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());
+}
+
+void QAndroidViewSignalManager::forwardSignal(int signalValue)
+{
+ invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
+}
+
+void QAndroidViewSignalManager::forwardSignal(bool signalValue)
+{
+ invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
+}
+
+void QAndroidViewSignalManager::forwardSignal(double signalValue)
+{
+ invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
+}
+
+void QAndroidViewSignalManager::forwardSignal(float signalValue)
+{
+ invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
+}
+
+void QAndroidViewSignalManager::forwardSignal(QString signalValue)
+{
+ invokeListener(sender(), senderSignalIndex(), QVariant(signalValue));
+}
+
+void QAndroidViewSignalManager::invokeListener(QObject *sender, int senderSignalIndex,
+ QVariant signalValue)
+{
+ using namespace QtJniTypes;
+
+ const QMetaObject *metaObject = sender->metaObject();
+ const QMetaMethod signalMethod = metaObject->method(senderSignalIndex);
+
+ for (auto connectionInfoIter = connectionInfoMap.constFind(signalMethod.methodSignature());
+ connectionInfoIter != connectionInfoMap.constEnd()
+ && connectionInfoIter.key() == signalMethod.methodSignature();
+ ++connectionInfoIter) {
+ const ConnectionInfo connectionInfo = *connectionInfoIter;
+ const QByteArray javaArgType = connectionInfo.javaArgType;
+ QJniObject jSignalMethodName =
+ QJniObject::fromString(QLatin1StringView(signalMethod.name()));
+
+ 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:
+ qWarning("Mismatching argument types between QML signal (%s) and the Java function "
+ "(%s). Sending null as argument.",
+ signalMethod.methodSignature().constData(), javaArgType.constData());
+ }
+
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread(
+ [connectionInfo, jSignalMethodName, jValue]() {
+ connectionInfo.listener.callMethod<void, jstring, jobject>(
+ "onSignalEmitted", jSignalMethodName.object<jstring>(),
+ jValue.object());
+ });
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/platform/android/qandroidviewsignalmanager_p.h b/src/quick/platform/android/qandroidviewsignalmanager_p.h
new file mode 100644
index 0000000000..80dfc823fb
--- /dev/null
+++ b/src/quick/platform/android/qandroidviewsignalmanager_p.h
@@ -0,0 +1,64 @@
+// 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 QANDROIDVIEWSIGNALMANAGER_P_H
+#define QANDROIDVIEWSIGNALMANAGER_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/qobject.h>
+#include <QtCore/qjnitypes.h>
+#include <QtQuick/qquickview.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidViewSignalManager : public QObject
+{
+ Q_OBJECT
+public:
+ struct ConnectionInfo
+ {
+ int id;
+ QJniObject listener;
+ QByteArray javaArgType;
+ QByteArray signalSignature;
+ int propertyIndex{ -1 };
+ };
+
+ explicit QAndroidViewSignalManager(QQuickView *parent)
+ : QObject(parent), connectionHandleCounter(0)
+ {
+ }
+ void invokeListener(QObject *sender, int senderSignalIndex, QVariant signalValue);
+
+ int connectionHandleCounter;
+ 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);
+ void forwardSignal(double);
+ void forwardSignal(float);
+ void forwardSignal(bool);
+ void forwardSignal(QString);
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDVIEWSIGNALMANAGER_P_H