From f939c18d169c696256c1e963dc4fd182eb1c0fbb Mon Sep 17 00:00:00 2001 From: Petri Virkkunen Date: Tue, 20 Feb 2024 14:06:16 +0200 Subject: [PATCH] Android: Enable QML embedding in services Need a convenient way to access QtServiceEmbeddedDelegate from native and create via QtView, so extend embedded delegate factory to handle creating them. QtView now initializes a QtEmbeddedViewInterface via QtEmbeddedViewInterfaceFactory, which now has a generic create() API that takes a Context object, and creates/returns a proper Service or Activity delegate. Task-number: QTBUG-118874 Change-Id: I8b04b280b9234f3ac3ab818b2d333430d1ac4e41 Reviewed-by: Assam Boudjelthia --- src/android/jar/CMakeLists.txt | 2 +- .../qt/android/QtEmbeddedDelegate.java | 2 +- .../qt/android/QtEmbeddedDelegateFactory.java | 37 ------------------- .../qt/android/QtEmbeddedLoader.java | 2 +- .../QtEmbeddedViewInterfaceFactory.java | 34 +++++++++++++++++ .../qt/android/QtServiceEmbeddedDelegate.java | 1 + .../src/org/qtproject/qt/android/QtView.java | 2 +- 7 files changed, 39 insertions(+), 41 deletions(-) delete mode 100644 src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegateFactory.java create mode 100644 src/android/jar/src/org/qtproject/qt/android/QtEmbeddedViewInterfaceFactory.java diff --git a/src/android/jar/CMakeLists.txt b/src/android/jar/CMakeLists.txt index b24c8d91001..b786354a21a 100644 --- a/src/android/jar/CMakeLists.txt +++ b/src/android/jar/CMakeLists.txt @@ -35,7 +35,7 @@ set(java_sources src/org/qtproject/qt/android/QtWindow.java src/org/qtproject/qt/android/QtActivityDelegateBase.java src/org/qtproject/qt/android/QtEmbeddedDelegate.java - src/org/qtproject/qt/android/QtEmbeddedDelegateFactory.java + src/org/qtproject/qt/android/QtEmbeddedViewInterfaceFactory.java src/org/qtproject/qt/android/QtEmbeddedLoader.java src/org/qtproject/qt/android/QtView.java src/org/qtproject/qt/android/QtEmbeddedViewInterface.java diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java index 5706eedb67a..5298ac02bdf 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java @@ -81,7 +81,7 @@ class QtEmbeddedDelegate extends QtActivityDelegateBase if (m_activity == activity && m_stateDetails.isStarted) { m_activity.getApplication().unregisterActivityLifecycleCallbacks(this); QtNative.unregisterAppStateListener(QtEmbeddedDelegate.this); - QtEmbeddedDelegateFactory.remove(m_activity); + QtEmbeddedViewInterfaceFactory.remove(m_activity); QtNative.terminateQt(); QtNative.setActivity(null); QtNative.getQtThread().exit(); diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegateFactory.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegateFactory.java deleted file mode 100644 index 8cf89e5bc37..00000000000 --- a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegateFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -// 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.app.Activity; -import android.app.Application; -import android.os.Bundle; - -import java.util.HashMap; - -class QtEmbeddedDelegateFactory { - private static final HashMap m_delegates = new HashMap<>(); - private static final Object m_delegateLock = new Object(); - - @UsedFromNativeCode - public static QtActivityDelegateBase getActivityDelegate(Activity activity) { - synchronized (m_delegateLock) { - return m_delegates.get(activity); - } - } - - public static QtEmbeddedDelegate create(Activity activity) { - synchronized (m_delegateLock) { - if (!m_delegates.containsKey(activity)) - m_delegates.put(activity, new QtEmbeddedDelegate(activity)); - - return m_delegates.get(activity); - } - } - - public static void remove(Activity activity) { - synchronized (m_delegateLock) { - m_delegates.remove(activity); - } - } -} diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedLoader.java index 0c6c4b49f0f..69ecced7ff4 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedLoader.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedLoader.java @@ -48,6 +48,6 @@ class QtEmbeddedLoader extends QtLoader { protected void finish() { // Called when loading fails - clear the delegate to make sure we don't hold reference // to the embedding Context - QtEmbeddedDelegateFactory.remove((Activity)m_context.getBaseContext()); + QtEmbeddedViewInterfaceFactory.remove((Activity)m_context.getBaseContext()); } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedViewInterfaceFactory.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedViewInterfaceFactory.java new file mode 100644 index 00000000000..8a5764e93fe --- /dev/null +++ b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedViewInterfaceFactory.java @@ -0,0 +1,34 @@ +// 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.app.Activity; +import android.app.Service; + +import java.util.HashMap; + +class QtEmbeddedViewInterfaceFactory { + private static final HashMap m_interfaces = new HashMap<>(); + private static final Object m_interfaceLock = new Object(); + + public static QtEmbeddedViewInterface create(Context context) { + synchronized (m_interfaceLock) { + if (!m_interfaces.containsKey(context)) { + if (context instanceof Activity) + m_interfaces.put(context, new QtEmbeddedDelegate((Activity)context)); + else if (context instanceof Service) + m_interfaces.put(context, new QtServiceEmbeddedDelegate((Service)context)); + } + + return m_interfaces.get(context); + } + } + + public static void remove(Context context) { + synchronized (m_interfaceLock) { + m_interfaces.remove(context); + } + } +} diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java index 6ee2d53791b..d8af626ca0f 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java @@ -102,6 +102,7 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App { QtNative.setApplicationState(ApplicationSuspended); QtNative.unregisterAppStateListener(QtServiceEmbeddedDelegate.this); + QtEmbeddedViewInterfaceFactory.remove(m_service); QtNative.terminateQt(); QtNative.setService(null); diff --git a/src/android/jar/src/org/qtproject/qt/android/QtView.java b/src/android/jar/src/org/qtproject/qt/android/QtView.java index ddf70b3b5b9..530b1768e75 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtView.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtView.java @@ -60,7 +60,7 @@ abstract class QtView extends ViewGroup { } QtEmbeddedLoader loader = new QtEmbeddedLoader(context); - m_viewInterface = QtEmbeddedDelegateFactory.create((Activity)context); + m_viewInterface = QtEmbeddedViewInterfaceFactory.create(context); loader.setMainLibraryName(appLibName); addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override