diff options
| author | Tinja Paavoseppä <tinja.paavoseppa@qt.io> | 2023-09-05 13:26:42 +0300 |
|---|---|---|
| committer | Tinja Paavoseppä <tinja.paavoseppa@qt.io> | 2024-02-15 10:07:04 +0200 |
| commit | 1d1ba46f54bcec6449d285c8f1f71540cdb02015 (patch) | |
| tree | b7b32e06ca1d88fa9e3f259e069b57f4a851be88 | |
| parent | 560fe5a9fe57bcb245a6a7162450e826849061cb (diff) | |
Android: Add QtQuickView class to embed QQuickView to Android
Add Java class QtQuickView to enable embedding a QQuickView to
an Android app form Java or Kotlin. Also add a JNI helper method
to be able to create the QQuickView from Java/Kotlin.
Pick-to: 6.7
Task-number: QTBUG-116953
Change-Id: I131eb84f3247fea3ec8d08612e6dd6567f5dca83
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
| -rw-r--r-- | src/quick/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | src/quick/jar/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | src/quick/jar/org/qtproject/qt/android/QtQuickView.java | 32 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidquickviewembedding.cpp | 69 | ||||
| -rw-r--r-- | src/quick/platform/android/qandroidquickviewembedding_p.h | 34 |
5 files changed, 157 insertions, 0 deletions
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index 19652fb603..097918a3cf 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -559,6 +559,17 @@ qt_internal_extend_target(Quick CONDITION IOS OR MACOS scenegraph/qsgrhisupport_mac.mm ) +qt_internal_extend_target(Quick CONDITION ANDROID + SOURCES + platform/android/qandroidquickviewembedding.cpp platform/android/qandroidquickviewembedding_p.h +) +if (ANDROID) + add_subdirectory(jar) + set_property(TARGET Quick PROPERTY QT_ANDROID_BUNDLED_JAR_DEPENDENCIES + jar/Qt${QtDeclarative_VERSION_MAJOR}AndroidQuick.jar + ) +endif() + qt_internal_extend_target(Quick CONDITION QT_FEATURE_thread SOURCES scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop_p.h diff --git a/src/quick/jar/CMakeLists.txt b/src/quick/jar/CMakeLists.txt new file mode 100644 index 0000000000..083759d4c4 --- /dev/null +++ b/src/quick/jar/CMakeLists.txt @@ -0,0 +1,11 @@ +qt_internal_add_jar(Qt${QtDeclarative_VERSION_MAJOR}AndroidQuick + INCLUDE_JARS + ${QT_ANDROID_JAR} + ${QT6_INSTALL_PREFIX}/jar/Qt${QtDeclarative_VERSION_MAJOR}Android.jar + SOURCES org/qtproject/qt/android/QtQuickView.java + OUTPUT_DIR "${QT_BUILD_DIR}/jar") + +install_jar(Qt${QtDeclarative_VERSION_MAJOR}AndroidQuick + DESTINATION jar + COMPONENT Devel +) diff --git a/src/quick/jar/org/qtproject/qt/android/QtQuickView.java b/src/quick/jar/org/qtproject/qt/android/QtQuickView.java new file mode 100644 index 0000000000..dbd91f72a9 --- /dev/null +++ b/src/quick/jar/org/qtproject/qt/android/QtQuickView.java @@ -0,0 +1,32 @@ +// 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 + +package org.qtproject.qt.android; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import java.security.InvalidParameterException; + +public class QtQuickView extends QtView { + private String m_qmlUri; + + native void createQuickView(String qmlUri, int width, int height, long parentWindowReference); + + public QtQuickView(Context context, String qmlUri, String appName) + throws InvalidParameterException { + super(context, appName); + if (qmlUri == null || qmlUri.isEmpty()) { + throw new InvalidParameterException( + "QtQuickView: argument 'qmlUri' may not be empty or null"); + } + + m_qmlUri = qmlUri; + } + + @Override + protected void createWindow(long parentWindowReference) { + createQuickView(m_qmlUri, getWidth(), getHeight(), parentWindowReference); + } +} diff --git a/src/quick/platform/android/qandroidquickviewembedding.cpp b/src/quick/platform/android/qandroidquickviewembedding.cpp new file mode 100644 index 0000000000..2a1bd81b83 --- /dev/null +++ b/src/quick/platform/android/qandroidquickviewembedding.cpp @@ -0,0 +1,69 @@ +// Copyright (C) 2023 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/qandroidquickviewembedding_p.h> + +#include <QtCore/qjnienvironment.h> +#include <QtCore/qjniobject.h> +#include <QtCore/qjnitypes.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_JNI_CLASS(QtDelegate, "org/qtproject/qt/android/QtEmbeddedContextDelegate"); +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"); + +namespace QtAndroidQuickViewEmbedding +{ + void createQuickView(JNIEnv*, jobject nativeWindow, jstring qmlUri, jint width, jint height, + jlong parentWindowReference) + { + static_assert (sizeof(jlong) >= sizeof(void*), + "Insufficient size of Java type to hold the c++ pointer"); + const QUrl qmlUrl(QJniObject(qmlUri).toString()); + QMetaObject::invokeMethod(qApp, [qtViewObject = QJniObject(nativeWindow), + parentWindowReference, + width, + height, + qmlUrl] { + QWindow *parentWindow = reinterpret_cast<QWindow *>(parentWindowReference); + QQuickView* view = new QQuickView(parentWindow); + view->setSource(qmlUrl); + view->setColor(QColor(Qt::transparent)); + view->setWidth(width); + view->setHeight(height); + const QtJniTypes::QtWindow window = reinterpret_cast<jobject>(view->winId()); + qtViewObject.callMethod<void>("addQtWindow", + window, + reinterpret_cast<jlong>(view), + parentWindowReference); + }); + } + + bool registerNatives(QJniEnvironment& env) { + return env.registerNativeMethods(QtJniTypes::Traits<QtJniTypes::QtQuickView>::className(), + {Q_JNI_NATIVE_SCOPED_METHOD(createQuickView, + QtAndroidQuickViewEmbedding)}); + } +} + +Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) +{ + Q_UNUSED(vm) + Q_UNUSED(reserved) + + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + + QJniEnvironment env; + if (!env.isValid()) + return JNI_ERR; + if (!QtAndroidQuickViewEmbedding::registerNatives(env)) + return JNI_ERR; + return JNI_VERSION_1_6; +} + +QT_END_NAMESPACE diff --git a/src/quick/platform/android/qandroidquickviewembedding_p.h b/src/quick/platform/android/qandroidquickviewembedding_p.h new file mode 100644 index 0000000000..04ab169321 --- /dev/null +++ b/src/quick/platform/android/qandroidquickviewembedding_p.h @@ -0,0 +1,34 @@ +// Copyright (C) 2023 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 QANDROIDQUICKVIEWEMBEDDING_P_H +#define QANDROIDQUICKVIEWEMBEDDING_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/qjnienvironment.h> +#include <QtCore/qjnitypes.h> +#include <QtQuick/qquickview.h> + +QT_BEGIN_NAMESPACE + +namespace QtAndroidQuickViewEmbedding +{ + bool registerNatives(QJniEnvironment& env); + void createQuickView(JNIEnv *env, jobject nativeWindow, jstring qmlUri, jint width, jint height, + jlong parentWindowReference); + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(createQuickView) +}; + +QT_END_NAMESPACE + +#endif // QANDROIDQUICKVIEWEMBEDDING_P_H |
