diff options
author | Petri Virkkunen <petri.virkkunen@qt.io> | 2024-02-15 09:52:12 +0200 |
---|---|---|
committer | Petri Virkkunen <petri.virkkunen@qt.io> | 2024-04-30 22:17:04 +0300 |
commit | aa1e658755289f52c61c1e9f2ab1bec6f214b6a4 (patch) | |
tree | 4331782da837ac57cfbfb2c5e85d22683fc5c214 | |
parent | f1fa33aeb3757d67785550953d3ae0c25a512cb7 (diff) |
Android: Add delegate class for embedding QML into Android Services
QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface to allow
QtView communication, listens to Qt plugin load state and loads
embedded views.
Task-number: QTBUG-118874
Change-Id: I673eefd8da425c96af436b2286899f699752d60a
Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
-rw-r--r-- | src/android/jar/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java | 115 |
2 files changed, 116 insertions, 0 deletions
diff --git a/src/android/jar/CMakeLists.txt b/src/android/jar/CMakeLists.txt index e5fa7a95b6..c36bbdf75b 100644 --- a/src/android/jar/CMakeLists.txt +++ b/src/android/jar/CMakeLists.txt @@ -39,6 +39,7 @@ set(java_sources src/org/qtproject/qt/android/QtEmbeddedLoader.java src/org/qtproject/qt/android/QtView.java src/org/qtproject/qt/android/QtEmbeddedViewInterface.java + src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java ) qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}Android diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java new file mode 100644 index 0000000000..e5fd397857 --- /dev/null +++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java @@ -0,0 +1,115 @@ +// 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 static org.qtproject.qt.android.QtNative.ApplicationState.ApplicationSuspended; + +import android.app.Service; +import android.content.Context; +import android.content.res.Resources; +import android.hardware.display.DisplayManager; +import android.view.Display; +import android.view.View; +import android.util.DisplayMetrics; + +/** + * QtServiceEmbeddedDelegate is used for embedding QML into Android Service contexts. Implements + * {@link QtEmbeddedViewInterface} so it can be used by QtView to communicate with the Qt layer. + */ +class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.AppStateDetailsListener +{ + private final Service m_service; + private QtView m_view; + private boolean m_windowLoaded = false; + + QtServiceEmbeddedDelegate(Service service) + { + m_service = service; + QtNative.registerAppStateListener(this); + QtNative.setService(service); + } + + @UsedFromNativeCode + QtInputDelegate getInputDelegate() + { + // TODO Implement text input (QTBUG-122552) + return null; + } + + @Override + public void onAppStateDetailsChanged(QtNative.ApplicationStateDetails details) + { + synchronized (this) { + if (details.nativePluginIntegrationReady) { + QtNative.runAction(() -> { + if (m_view == null) + return; + + final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); + + final int maxWidth = m_view.getWidth(); + final int maxHeight = m_view.getHeight(); + final int width = maxWidth; + final int height = maxHeight; + final int insetLeft = m_view.getLeft(); + final int insetTop = m_view.getTop(); + + final DisplayManager dm = m_service.getSystemService(DisplayManager.class); + QtDisplayManager.setDisplayMetrics( + maxWidth, maxHeight, insetLeft, insetTop, width, height, + QtDisplayManager.getXDpi(metrics), QtDisplayManager.getYDpi(metrics), + metrics.scaledDensity, metrics.density, + QtDisplayManager.getRefreshRate( + dm.getDisplay(Display.DEFAULT_DISPLAY))); + }); + createRootWindow(); + } + } + } + + // QtEmbeddedViewInterface implementation begin + @Override + public void startQtApplication(String appParams, String mainLib) + { + QtNative.startApplication(appParams, mainLib); + } + + @Override + public void setView(QtView view) + { + m_view = view; + // If the embedded view is destroyed, do cleanup: + if (view == null) + cleanup(); + } + + @Override + public void queueLoadWindow() + { + synchronized (this) { + if (QtNative.getStateDetails().nativePluginIntegrationReady) + createRootWindow(); + } + } + // QtEmbeddedViewInterface implementation end + + private void createRootWindow() + { + if (m_view != null && !m_windowLoaded) { + QtView.createRootWindow(m_view, m_view.getLeft(), m_view.getTop(), m_view.getWidth(), + m_view.getHeight()); + m_windowLoaded = true; + } + } + + private void cleanup() + { + QtNative.setApplicationState(ApplicationSuspended); + QtNative.unregisterAppStateListener(QtServiceEmbeddedDelegate.this); + + QtNative.terminateQt(); + QtNative.setService(null); + QtNative.getQtThread().exit(); + } +} |