diff options
Diffstat (limited to 'src/plugins/platforms/android')
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; | 
