summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android/androidjnimain.cpp
diff options
context:
space:
mode:
authorTinja Paavoseppä <[email protected]>2023-09-05 12:58:40 +0300
committerTinja Paavoseppä <[email protected]>2024-01-30 20:01:29 +0200
commit702c420f51d9d56ca056315387f224ec2dba3ff3 (patch)
treef704654ac67fdc42cb019969eca0f003cf4a4bbf /src/plugins/platforms/android/androidjnimain.cpp
parentb3441b4127813148a701b7d538453bfdbe2315a4 (diff)
Android: Add classes to embed QML into native Android
Add classes that make it possible to add QML as a View into a native Android app: QtView: Base class for QtQuickView, handles non-Quick dependent operations. In essence a Java ViewGroup class which loads a QWindow and embeds it into itself. QtEmbeddedLoader: Extends QtLoader for embedded case, creates the embedded version of QtActivityDelegate and provides an embedded-specific path to loading Qt libraries (Mostly just allows users to set the name of the main lib) QtAndroidWindowEmbedding namespace: Deals with calls from QtEmbeddedDelegate to create/destroy QWindow and from QtView to show the window. Take the QtEmbeddedDelegate introduced in an earlier commit into use, and add functionality for loading QWindows for QtViews and managing QtViews into it. Add a factory for creating instances of QtEmbeddedDelegate. The factory holds a map of QtEmbeddedDelegate objects and creates them, with the Activity as the key. This is to make it so that the same delegate can be used by multiple views which share the same Context. Known issues left: * keyboard focus not working, as with other child windows Pick-to: 6.7 Task-number: QTBUG-118872 Change-Id: I94a5f9b4f904c05cc6368cf20f273fcf10d31f17 Reviewed-by: Assam Boudjelthia <[email protected]>
Diffstat (limited to 'src/plugins/platforms/android/androidjnimain.cpp')
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index bf15213b66f..206bbd03d66 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -13,6 +13,7 @@
#include "androidjniinput.h"
#include "androidjnimain.h"
#include "androidjnimenu.h"
+#include "androidwindowembedding.h"
#include "qandroidassetsfileenginehandler.h"
#include "qandroideventdispatcher.h"
#include "qandroidplatformdialoghelpers.h"
@@ -92,6 +93,8 @@ static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
Q_CONSTINIT static QBasicAtomicInt startQtAndroidPluginCalled = Q_BASIC_ATOMIC_INITIALIZER(0);
+Q_DECLARE_JNI_CLASS(QtEmbeddedDelegateFactory, "org/qtproject/qt/android/QtEmbeddedDelegateFactory")
+
namespace QtAndroid
{
QBasicMutex *platformInterfaceMutex()
@@ -187,10 +190,17 @@ namespace QtAndroid
// FIXME: avoid direct access to QtActivityDelegate
QtJniTypes::QtActivityDelegateBase qtActivityDelegate()
{
+ using namespace QtJniTypes;
if (!m_activityDelegate.isValid()) {
- auto activity = QtAndroidPrivate::activity();
- m_activityDelegate = activity.callMethod<QtJniTypes::QtActivityDelegateBase>(
- "getActivityDelegate");
+ if (isQtApplication()) {
+ auto context = QtAndroidPrivate::activity();
+ m_activityDelegate = context.callMethod<QtActivityDelegateBase>("getActivityDelegate");
+ } else {
+ m_activityDelegate = QJniObject::callStaticMethod<QtActivityDelegateBase>(
+ Traits<QtEmbeddedDelegateFactory>::className(),
+ "getActivityDelegate",
+ QtAndroidPrivate::activity());
+ }
}
return m_activityDelegate;
@@ -213,11 +223,15 @@ namespace QtAndroid
// embedded into a native Android app, where the Activity/Service is created
// by the user, outside of Qt, and Qt content is added as a view.
JNIEnv *env = QJniEnvironment::getJniEnv();
- static const jint isQtActivity = env->IsInstanceOf(QtAndroidPrivate::activity().object(),
- m_qtActivityClass);
- static const jint isQtService = env->IsInstanceOf(QtAndroidPrivate::service().object(),
- m_qtServiceClass);
- return isQtActivity || isQtService;
+ auto activity = QtAndroidPrivate::activity();
+ if (activity.isValid())
+ return env->IsInstanceOf(activity.object(), m_qtActivityClass);
+ auto service = QtAndroidPrivate::service();
+ if (service.isValid())
+ return env->IsInstanceOf(QtAndroidPrivate::service().object(), m_qtServiceClass);
+ // return true as default as Qt application is our default use case.
+ // famous last words: we should not end up here
+ return true;
}
void notifyAccessibilityLocationChange(uint accessibilityObjectId)
@@ -870,7 +884,8 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|| !QtAndroidAccessibility::registerNatives(env)
|| !QtAndroidDialogHelpers::registerNatives(env)
|| !QAndroidPlatformClipboard::registerNatives(env)
- || !QAndroidPlatformWindow::registerNatives(env)) {
+ || !QAndroidPlatformWindow::registerNatives(env)
+ || !QtAndroidWindowEmbedding::registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
}