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 <assam.boudjelthia@qt.io>
This commit is contained in:
Petri Virkkunen 2024-02-20 14:06:16 +02:00
parent 6bee03629f
commit f939c18d16
7 changed files with 39 additions and 41 deletions

View File

@ -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

View File

@ -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();

View File

@ -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<Activity, QtEmbeddedDelegate> 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);
}
}
}

View File

@ -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());
}
}

View File

@ -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<Context, QtEmbeddedViewInterface> 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);
}
}
}

View File

@ -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);

View File

@ -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