From 9cd561f355b82bf5016a0ac103a1ef0f97a20260 Mon Sep 17 00:00:00 2001 From: Petri Virkkunen Date: Mon, 2 Sep 2024 15:40:49 +0300 Subject: [PATCH] Android: Add support for multiple embedded views in Android Service To enable adding and managing multiple QtQuickViews, QtServiceEmbeddedDelegate now hosts a set of QtViews instead of a single one. To avoid crashing if the QML view has a TextField, do not allow QtWindow to create a QtEditText if the service usecase is detected. Fixes: QTBUG-129412 Task-number: QTBUG-127422 Task-number: QTBUG-128563 Change-Id: I70784657ed6cb2aa853160605f4663e517f0e6db Reviewed-by: Assam Boudjelthia (cherry picked from commit 1656a2f58c759c25e6a89435a65c1d0fceba8a09) --- .../qt/android/QtServiceEmbeddedDelegate.java | 40 ++++++++----------- .../org/qtproject/qt/android/QtWindow.java | 4 +- 2 files changed, 19 insertions(+), 25 deletions(-) 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 36a56947ea6..d59975da877 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java @@ -13,6 +13,8 @@ import android.view.Display; import android.view.View; import android.util.DisplayMetrics; +import java.util.HashSet; + /** * 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. @@ -20,8 +22,7 @@ import android.util.DisplayMetrics; class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.AppStateDetailsListener { private final Service m_service; - private QtView m_view; - private boolean m_windowLoaded = false; + private HashSet m_views = new HashSet(); QtServiceEmbeddedDelegate(Service service) { @@ -38,17 +39,14 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App synchronized (this) { if (ready) { 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 maxWidth = metrics.widthPixels; + final int maxHeight = metrics.heightPixels; final int width = maxWidth; final int height = maxHeight; - final int insetLeft = m_view.getLeft(); - final int insetTop = m_view.getTop(); + final int insetLeft = 0; + final int insetTop = 0; final DisplayManager dm = m_service.getSystemService(DisplayManager.class); QtDisplayManager.setDisplayMetrics( @@ -58,7 +56,6 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App QtDisplayManager.getRefreshRate( dm.getDisplay(Display.DEFAULT_DISPLAY))); }); - createRootWindow(); } } } @@ -73,30 +70,25 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App @Override public void addView(QtView view) { - m_view = view; - QtNative.runAction(() -> { - createRootWindow(); - }); + if (m_views.add(view)) { + QtNative.runAction(() -> createRootWindow(view)); + } } @Override public void removeView(QtView view) { - if (m_view == view) { - m_view = null; - m_windowLoaded = false; - // If the embedded view is destroyed, do cleanup: + m_views.remove(view); + if (m_views.isEmpty()) cleanup(); - } } // QtEmbeddedViewInterface implementation end - private void createRootWindow() + private void createRootWindow(QtView view) { - 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; + if (m_views.contains(view)) { + QtView.createRootWindow(view, view.getLeft(), view.getTop(), view.getWidth(), + view.getHeight()); } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java index 35de4858370..88078a843df 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java @@ -3,6 +3,7 @@ package org.qtproject.qt.android; +import android.app.Activity; import android.content.Context; import android.view.GestureDetector; import android.view.MotionEvent; @@ -42,7 +43,8 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { // to QAndroidPlatformWindow::setVisible(). setVisible(false); - if (!isForeignWindow) { + if (!isForeignWindow && context instanceof Activity) { + // TODO QTBUG-122552 - Service keyboard input not implemented m_editText = new QtEditText(context, listener); m_editText.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); QtNative.runAction(() -> {