diff options
author | Tinja Paavoseppä <[email protected]> | 2023-09-05 12:58:40 +0300 |
---|---|---|
committer | Tinja Paavoseppä <[email protected]> | 2024-01-30 20:01:29 +0200 |
commit | 702c420f51d9d56ca056315387f224ec2dba3ff3 (patch) | |
tree | f704654ac67fdc42cb019969eca0f003cf4a4bbf /src/plugins/platforms/android/androidjnimain.cpp | |
parent | b3441b4127813148a701b7d538453bfdbe2315a4 (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.cpp | 33 |
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; } |