diff options
Diffstat (limited to 'src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java')
-rw-r--r-- | src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java new file mode 100644 index 0000000000..ff694777d5 --- /dev/null +++ b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java @@ -0,0 +1,178 @@ +// 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.*; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.res.Resources; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; + +import java.util.ArrayList; +import java.util.HashMap; + +class QtEmbeddedDelegate extends QtActivityDelegateBase + implements QtNative.AppStateDetailsListener, QtEmbeddedViewInterface +{ + // TODO simplistic implementation with one QtView, expand to support multiple views QTBUG-117649 + private QtView m_view; + private QtNative.ApplicationStateDetails m_stateDetails; + private boolean m_windowLoaded = false; + + public QtEmbeddedDelegate(Activity context) { + super(context); + + m_stateDetails = QtNative.getStateDetails(); + QtNative.registerAppStateListener(this); + + m_activity.getApplication().registerActivityLifecycleCallbacks( + new Application.ActivityLifecycleCallbacks() { + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} + + @Override + public void onActivityStarted(Activity activity) {} + + @Override + public void onActivityResumed(Activity activity) { + if (m_activity == activity && m_stateDetails.isStarted) { + QtNative.setApplicationState(ApplicationActive); + QtNative.updateWindow(); + } + } + + @Override + public void onActivityPaused(Activity activity) { + if (m_activity == activity && m_stateDetails.isStarted) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || + !activity.isInMultiWindowMode()) { + QtNative.setApplicationState(ApplicationInactive); + } + } + } + + @Override + public void onActivityStopped(Activity activity) { + if (m_activity == activity && m_stateDetails.isStarted) { + QtNative.setApplicationState(ApplicationSuspended); + } + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} + + @Override + public void onActivityDestroyed(Activity activity) { + if (m_activity == activity && m_stateDetails.isStarted) { + m_activity.getApplication().unregisterActivityLifecycleCallbacks(this); + QtNative.unregisterAppStateListener(QtEmbeddedDelegate.this); + QtEmbeddedDelegateFactory.remove(m_activity); + QtNative.terminateQt(); + QtNative.setActivity(null); + QtNative.getQtThread().exit(); + } + } + }); + } + + @Override + public void onAppStateDetailsChanged(QtNative.ApplicationStateDetails details) { + synchronized (this) { + m_stateDetails = details; + } + } + + @Override + public void onNativePluginIntegrationReadyChanged(boolean ready) + { + synchronized (this) { + if (ready) { + QtNative.runAction(() -> { + DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); + QtDisplayManager.setApplicationDisplayMetrics(m_activity, metrics.widthPixels, + metrics.heightPixels); + + }); + createRootWindow(); + } + } + } + + @Override + void startNativeApplicationImpl(String appParams, String mainLib) + { + QtNative.startApplication(appParams, mainLib); + } + + @Override + QtAccessibilityDelegate createAccessibilityDelegate() + { + // FIXME make QtAccessibilityDelegate window based or verify current way works + // also for child windows: QTBUG-120685 + return null; + } + + @UsedFromNativeCode + @Override + QtLayout getQtLayout() + { + // TODO verify if returning m_view here works, this is used by the androidjniinput + // when e.g. showing a keyboard, so depends on getting the keyboard focus working + // QTBUG-118873 + if (m_view == null) + return null; + return m_view.getQtWindow(); + } + + // QtEmbeddedViewInterface implementation begin + @Override + public void startQtApplication(String appParams, String mainLib) + { + super.startNativeApplication(appParams, mainLib); + } + + @Override + public void queueLoadWindow() + { + synchronized (this) { + if (m_stateDetails.nativePluginIntegrationReady) + createRootWindow(); + } + } + + @Override + public void setView(QtView view) + { + m_view = view; + updateInputDelegate(); + if (m_view != null) + registerGlobalFocusChangeListener(m_view); + } + // QtEmbeddedViewInterface implementation end + + private void updateInputDelegate() { + if (m_view == null) { + m_inputDelegate.setEditPopupMenu(null); + return; + } + m_inputDelegate.setEditPopupMenu(new EditPopupMenu(m_activity, m_view)); + } + + 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; + } + } +} |