summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/android')
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp16
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp73
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp3
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp6
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp53
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h5
7 files changed, 80 insertions, 78 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index a1edf49da12..6154f4121d2 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -470,7 +470,6 @@ namespace QtAndroidAccessibility
case QAccessible::Role::Link:
{
if (state.checkable)
- // There is also a android.widget.Switch for which we have no match.
return QStringLiteral("android.widget.ToggleButton");
return QStringLiteral("android.widget.Button");
}
@@ -478,6 +477,8 @@ namespace QtAndroidAccessibility
// As of android/accessibility/utils/Role.java::getRole a CheckBox
// is NOT android.widget.CheckBox
return QStringLiteral("android.widget.CompoundButton");
+ case QAccessible::Role::Switch:
+ return QStringLiteral("android.widget.Switch");
case QAccessible::Role::Clock:
return QStringLiteral("android.widget.TextClock");
case QAccessible::Role::ComboBox:
@@ -725,9 +726,18 @@ namespace QtAndroidAccessibility
break;
}
+ float min = info.minValue.toFloat();
+ float max = info.maxValue.toFloat();
+ float current = info.currentValue.toFloat();
+ if (info.role == QAccessible::ProgressBar) {
+ rangeType = 2; // RANGE_TYPE_PERCENT
+ current = 100 * (current - min) / (max - min);
+ min = 0.0f;
+ max = 100.0f;
+ }
+
QJniObject rangeInfo("android/view/accessibility/AccessibilityNodeInfo$RangeInfo",
- "(IFFF)V", rangeType, info.minValue.toFloat(),
- info.maxValue.toFloat(), info.currentValue.toFloat());
+ "(IFFF)V", rangeType, min, max, current);
if (rangeInfo.isValid()) {
env->CallVoidMethod(node, m_setRangeInfoMethodID, rangeInfo.object());
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 8c5335d9c31..9059fab757b 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -359,20 +359,41 @@ namespace QtAndroid
static bool initJavaReferences(QJniEnvironment &env);
-static void initializeBackends()
+static bool initAndroidQpaPlugin(JNIEnv *jenv, jobject object)
{
+ Q_UNUSED(jenv)
+ Q_UNUSED(object)
+
+ // Init all the Java refs, if they haven't already been initialized. They get initialized
+ // when the library is loaded, but in case Qt is terminated, they are cleared, and in case
+ // Qt is then started again JNI_OnLoad will not be called again, since the library is already
+ // loaded - in that case we need to init again here, hence the check.
+ // TODO QTBUG-130614 QtCore also inits some Java references in qjnihelpers - we probably
+ // want to reset those, too.
+ QJniEnvironment qEnv;
+ if (!qEnv.isValid()) {
+ qCritical() << "Failed to initialize the JNI Environment";
+ return false;
+ }
+
+ if (!initJavaReferences(qEnv))
+ return false;
+
+ m_androidPlatformIntegration = nullptr;
+
// File engine handler instantiation registers the handler
m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
m_androidContentFileEngineHandler = new AndroidContentFileEngineHandler();
m_androidApkFileEngineHandler = new QAndroidApkFileEngineHandler();
m_backendRegister = new AndroidBackendRegister();
-}
-static bool initCleanupHandshakeSemaphores()
-{
- return sem_init(&m_exitSemaphore, 0, 0) != -1
- && sem_init(&m_stopQtSemaphore, 0, 0) != -1;
+ if (sem_init(&m_exitSemaphore, 0, 0) == -1 && sem_init(&m_stopQtSemaphore, 0, 0) == -1) {
+ qCritical() << "Failed to init Qt application cleanup semaphores";
+ return false;
+ }
+
+ return true;
}
static void startQtNativeApplication(JNIEnv *jenv, jobject object, jstring paramsString)
@@ -391,23 +412,6 @@ static void startQtNativeApplication(JNIEnv *jenv, jobject object, jstring param
vm->AttachCurrentThread(&env, &args);
}
- // Init all the Java refs, if they haven't already been initialized. They get initialized
- // when the library is loaded, but in case Qt is terminated, they are cleared, and in case
- // Qt is then started again JNI_OnLoad will not be called again, since the library is already
- // loaded - in that case we need to init again here, hence the check.
- // TODO QTBUG-130614 QtCore also inits some Java references in qjnihelpers - we probably
- // want to reset those, too.
- QJniEnvironment qEnv;
- if (!qEnv.isValid()) {
- qCritical() << "Failed to initialize the JNI Environment";
- return;
- }
- if (!initJavaReferences(qEnv))
- return;
-
- m_androidPlatformIntegration = nullptr;
- initializeBackends();
-
const QStringList argsList = QProcess::splitCommand(QJniObject(paramsString).toString());
const int argc = argsList.size();
QVarLengthArray<char *> argv(argc + 1);
@@ -444,11 +448,6 @@ static void startQtNativeApplication(JNIEnv *jenv, jobject object, jstring param
return;
}
- if (!initCleanupHandshakeSemaphores()) {
- qCritical() << "Failed to init Qt application cleanup semaphores";
- return;
- }
-
// Register type for invokeMethod() calls.
qRegisterMetaType<Qt::ScreenOrientation>("Qt::ScreenOrientation");
@@ -458,13 +457,6 @@ static void startQtNativeApplication(JNIEnv *jenv, jobject object, jstring param
startQtAndroidPluginCalled.fetchAndAddRelease(1);
- QtNative::callStaticMethod("setStarted", true);
-
- // The service must wait until the QCoreApplication starts,
- // otherwise onBind will be called too early.
- if (QtAndroidPrivate::service().isValid() && QtAndroid::isQtApplication())
- QtAndroidPrivate::waitForServiceSetup();
-
const int ret = m_main(argc, argv.data());
qInfo() << "main() returned" << ret;
@@ -540,6 +532,15 @@ static void clearJavaReferences(JNIEnv *env)
}
}
+static void waitForServiceSetup(JNIEnv *env, jclass /*clazz*/)
+{
+ Q_UNUSED(env);
+ // The service must wait until the QCoreApplication starts otherwise onBind will be
+ // called too early
+ if (QtAndroidPrivate::service().isValid() && QtAndroid::isQtApplication())
+ QtAndroidPrivate::waitForServiceSetup();
+}
+
static void terminateQtNativeApplication(JNIEnv *env, jclass /*clazz*/)
{
// QAndroidEventDispatcherStopper is stopped when the user uses the task manager
@@ -730,8 +731,10 @@ static jobject onBind(JNIEnv */*env*/, jclass /*cls*/, jobject intent)
}
static JNINativeMethod methods[] = {
+ { "initAndroidQpaPlugin", "()Z", (void *)initAndroidQpaPlugin },
{ "startQtNativeApplication", "(Ljava/lang/String;)V", (void *)startQtNativeApplication },
{ "terminateQtNativeApplication", "()V", (void *)terminateQtNativeApplication },
+ { "waitForServiceSetup", "()V", (void *)waitForServiceSetup },
{ "updateApplicationState", "(I)V", (void *)updateApplicationState },
{ "onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult },
{ "onNewIntent", "(Landroid/content/Intent;)V", (void *)onNewIntent },
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index ecbbddb2e36..1d755139b46 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -82,9 +82,6 @@ static bool hasValidFocusObject()
if (!m_androidInputContext)
return false;
- if (!m_androidInputContext->isInputPanelVisible())
- return false;
-
const auto focusObject = m_androidInputContext->focusObject();
if (!focusObject)
return false;
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index c8555cdc659..f64742ff133 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -291,7 +291,7 @@ void QAndroidPlatformScreen::topVisibleWindowChanged()
if (w && w->handle()) {
QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
if (platformWindow) {
- platformWindow->updateSystemUiVisibility();
+ platformWindow->updateSystemUiVisibility(w->windowStates(), w->flags());
platformWindow->updateFocusedEditText();
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 822a5357107..0d8673aac03 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -27,7 +27,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaMenus, "qt.qpa.menus")
-Q_DECLARE_JNI_CLASS(QtDisplayManager, "org/qtproject/qt/android/QtDisplayManager")
+Q_DECLARE_JNI_CLASS(QtWindowInsetsController, "org/qtproject/qt/android/QtWindowInsetsController")
using namespace Qt::StringLiterals;
@@ -448,9 +448,9 @@ void QAndroidPlatformTheme::requestColorScheme(Qt::ColorScheme scheme)
const auto iface = qGuiApp->nativeInterface<QNativeInterface::QAndroidApplication>();
iface->runOnAndroidMainThread([=]() {
bool isLight = scheme == Qt::ColorScheme::Light;
- QtJniTypes::QtDisplayManager::callStaticMethod("setStatusBarColorHint",
+ QtJniTypes::QtWindowInsetsController::callStaticMethod("setStatusBarColorHint",
iface->context().object<QtJniTypes::Activity>(), isLight);
- QtJniTypes::QtDisplayManager::callStaticMethod("setNavigationBarColorHint",
+ QtJniTypes::QtWindowInsetsController::callStaticMethod("setNavigationBarColorHint",
iface->context().object<QtJniTypes::Activity>(), isLight);
});
}
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index 937839ace0c..c4245998772 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -22,6 +22,7 @@ Q_DECLARE_JNI_CLASS(QtInputInterface, "org/qtproject/qt/android/QtInputInterface
Q_DECLARE_JNI_CLASS(QtInputConnectionListener,
"org/qtproject/qt/android/QtInputConnection$QtInputConnectionListener")
Q_DECLARE_JNI_CLASS(QtDisplayManager, "org/qtproject/qt/android/QtWindowInterface")
+Q_DECLARE_JNI_CLASS(QtWindowInsetsController, "org/qtproject/qt/android/QtWindowInsetsController")
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
: QPlatformWindow(window), m_nativeQtWindow(nullptr),
@@ -55,15 +56,12 @@ void QAndroidPlatformWindow::initialize()
isForeignWindow(), m_nativeParentQtWindow, listener);
m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
- m_windowFlags = Qt::Widget;
- m_windowState = Qt::WindowNoState;
// the surfaceType is overwritten in QAndroidPlatformOpenGLWindow ctor so let's save
// the fact that it's a raster window for now
m_isRaster = window->surfaceType() == QSurface::RasterSurface;
- setWindowState(window->windowStates());
// the following is in relation to the virtual geometry
- const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen);
+ const bool forceMaximize = window->windowStates() & (Qt::WindowMaximized | Qt::WindowFullScreen);
const QRect nativeScreenGeometry = platformScreen()->availableGeometry();
if (forceMaximize) {
setGeometry(nativeScreenGeometry);
@@ -122,7 +120,7 @@ void QAndroidPlatformWindow::raise()
QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::ActiveWindowFocusReason);
return;
}
- updateSystemUiVisibility();
+ updateSystemUiVisibility(window()->windowStates(), window()->flags());
platformScreen()->raise(this);
}
@@ -166,13 +164,13 @@ void QAndroidPlatformWindow::setVisible(bool visible)
if (!visible && window() == qGuiApp->focusWindow()) {
platformScreen()->topVisibleWindowChanged();
} else {
- updateSystemUiVisibility();
- if ((m_windowState & Qt::WindowFullScreen)
- || (window()->flags() & Qt::ExpandedClientAreaHint)) {
+ const Qt::WindowStates states = window()->windowStates();
+ const Qt::WindowFlags flags = window()->flags();
+ updateSystemUiVisibility(states, flags);
+ if (states & Qt::WindowFullScreen || flags & Qt::ExpandedClientAreaHint)
setGeometry(platformScreen()->geometry());
- } else if (m_windowState & Qt::WindowMaximized) {
+ else if (states & Qt::WindowMaximized)
setGeometry(platformScreen()->availableGeometry());
- }
requestActivateWindow();
}
}
@@ -187,27 +185,18 @@ void QAndroidPlatformWindow::setVisible(bool visible)
void QAndroidPlatformWindow::setWindowState(Qt::WindowStates state)
{
- if (m_windowState == state)
- return;
-
QPlatformWindow::setWindowState(state);
- m_windowState = state;
if (window()->isVisible())
- updateSystemUiVisibility();
+ updateSystemUiVisibility(state, window()->flags());
}
void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_windowFlags == flags)
- return;
+ QPlatformWindow::setWindowFlags(flags);
- m_windowFlags = flags;
-}
-
-Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const
-{
- return m_windowFlags;
+ if (window()->isVisible())
+ updateSystemUiVisibility(window()->windowStates(), flags);
}
void QAndroidPlatformWindow::setParent(const QPlatformWindow *window)
@@ -255,15 +244,21 @@ void QAndroidPlatformWindow::requestActivateWindow()
raise();
}
-void QAndroidPlatformWindow::updateSystemUiVisibility()
+void QAndroidPlatformWindow::updateSystemUiVisibility(Qt::WindowStates states, Qt::WindowFlags flags)
{
- const int flags = window()->flags();
const bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
if (!isNonRegularWindow) {
- const bool isFullScreen = (m_windowState & Qt::WindowFullScreen);
- const bool expandedToCutout = (flags & Qt::ExpandedClientAreaHint);
- QtAndroid::backendRegister()->callInterface<QtJniTypes::QtWindowInterface, void>(
- "setSystemUiVisibility", isFullScreen, expandedToCutout);
+ auto iface = qGuiApp->nativeInterface<QNativeInterface::QAndroidApplication>();
+ iface->runOnAndroidMainThread([=]() {
+ using namespace QtJniTypes;
+ auto activity = iface->context().object<Activity>();
+ if (states & Qt::WindowFullScreen)
+ QtWindowInsetsController::callStaticMethod("showFullScreen", activity);
+ else if (flags & Qt::ExpandedClientAreaHint)
+ QtWindowInsetsController::callStaticMethod("showExpanded", activity);
+ else
+ QtWindowInsetsController::callStaticMethod("showNormal", activity);
+ });
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index 07f4e12b35c..826a8d30ade 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -43,7 +43,6 @@ public:
void setWindowState(Qt::WindowStates state) override;
void setWindowFlags(Qt::WindowFlags flags) override;
- Qt::WindowFlags windowFlags() const;
void setParent(const QPlatformWindow *window) override;
WId winId() const override;
@@ -58,7 +57,7 @@ public:
void propagateSizeHints() override;
void requestActivateWindow() override;
- void updateSystemUiVisibility();
+ void updateSystemUiVisibility(Qt::WindowStates states, Qt::WindowFlags flags);
void updateFocusedEditText();
inline bool isRaster() const { return m_isRaster; }
bool isExposed() const override;
@@ -82,8 +81,6 @@ protected:
bool isEmbeddingContainer() const;
virtual void clearSurface() {}
- Qt::WindowFlags m_windowFlags;
- Qt::WindowStates m_windowState;
bool m_isRaster;
int m_nativeViewId = -1;