summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qjnihelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qjnihelpers.cpp')
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp484
1 files changed, 126 insertions, 358 deletions
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index 45f4a4d895..d900b74d37 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -1,54 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcoreapplication.h"
-#include "qjnienvironment.h"
+// Copyright (C) 2022 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
+
#include "qjnihelpers_p.h"
+
+#include "qjnienvironment.h"
#include "qjniobject.h"
#include "qlist.h"
#include "qmutex.h"
#include "qsemaphore.h"
-#include "qsharedpointer.h"
-#include "qthread.h"
-
-#include <QtCore/qrunnable.h>
+#include "qreadwritelock.h"
+#include <QtCore/private/qcoreapplication_p.h>
+#include <QtCore/private/qlocking_p.h>
+#include <android/log.h>
#include <deque>
#include <memory>
@@ -62,125 +26,53 @@ namespace QtAndroidPrivate {
ResumePauseListener::~ResumePauseListener() {}
void ResumePauseListener::handlePause() {}
void ResumePauseListener::handleResume() {}
- GenericMotionEventListener::~GenericMotionEventListener() {}
- KeyEventListener::~KeyEventListener() {}
}
static JavaVM *g_javaVM = nullptr;
static jobject g_jActivity = nullptr;
static jobject g_jService = nullptr;
static jobject g_jClassLoader = nullptr;
-static jint g_androidSdkVersion = 0;
-static jclass g_jNativeClass = nullptr;
-static jmethodID g_runPendingCppRunnablesMethodID = nullptr;
-static jmethodID g_hideSplashScreenMethodID = nullptr;
-Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
-static QBasicMutex g_pendingRunnablesMutex;
-
-Q_GLOBAL_STATIC_WITH_ARGS(QtAndroidPrivate::OnBindListener*, g_onBindListener, (nullptr));
-Q_GLOBAL_STATIC(QMutex, g_onBindListenerMutex);
+
+Q_CONSTINIT static QtAndroidPrivate::OnBindListener *g_onBindListener;
+Q_CONSTINIT static QBasicMutex g_onBindListenerMutex;
Q_GLOBAL_STATIC(QSemaphore, g_waitForServiceSetupSemaphore);
-Q_GLOBAL_STATIC(QAtomicInt, g_serviceSetupLockers);
+Q_CONSTINIT static QBasicAtomicInt g_serviceSetupLockers = Q_BASIC_ATOMIC_INITIALIZER(0);
-class PermissionsResultClass : public QObject
-{
- Q_OBJECT
-public:
- PermissionsResultClass(const QtAndroidPrivate::PermissionsResultFunc &func) : m_func(func) {}
- Q_INVOKABLE void sendResult(const QtAndroidPrivate::PermissionsHash &result) { m_func(result); delete this;}
-
-private:
- QtAndroidPrivate::PermissionsResultFunc m_func;
-};
-
-typedef QHash<int, PermissionsResultClass*> PendingPermissionRequestsHash;
-Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests);
-static QBasicMutex g_pendingPermissionRequestsMutex;
-static int nextRequestCode()
-{
- static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0);
- return counter.fetchAndAddRelaxed(1);
-}
+Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex);
-// function called from Java from Android UI thread
-static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/)
+static jboolean updateNativeActivity(JNIEnv *env, jclass = nullptr)
{
- for (;;) { // run all posted runnables
- QMutexLocker locker(&g_pendingRunnablesMutex);
- if (g_pendingRunnables->empty()) {
- break;
- }
- QtAndroidPrivate::Runnable runnable(std::move(g_pendingRunnables->front()));
- g_pendingRunnables->pop_front();
- locker.unlock();
- runnable(); // run it outside the sync block!
- }
-}
-namespace {
- struct GenericMotionEventListeners {
- QMutex mutex;
- QList<QtAndroidPrivate::GenericMotionEventListener *> listeners;
- };
+ jclass jQtNative = env->FindClass("org/qtproject/qt/android/QtNative");
+ if (QJniEnvironment::checkAndClearExceptions(env))
+ return JNI_FALSE;
- enum {
- PERMISSION_GRANTED = 0
- };
-}
-Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
+ jmethodID activityMethodID =
+ env->GetStaticMethodID(jQtNative, "activity", "()Landroid/app/Activity;");
+ if (QJniEnvironment::checkAndClearExceptions(env))
+ return JNI_FALSE;
-static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode,
- jobjectArray permissions, jintArray grantResults)
-{
- QMutexLocker locker(&g_pendingPermissionRequestsMutex);
- auto it = g_pendingPermissionRequests->find(requestCode);
- if (it == g_pendingPermissionRequests->end()) {
- // show an error or something ?
- return;
- }
- auto request = *it;
- g_pendingPermissionRequests->erase(it);
- locker.unlock();
-
- Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::QueuedConnection;
- QtAndroidPrivate::PermissionsHash hash;
- const int size = env->GetArrayLength(permissions);
- std::unique_ptr<jint[]> results(new jint[size]);
- env->GetIntArrayRegion(grantResults, 0, size, results.get());
- for (int i = 0 ; i < size; ++i) {
- const auto &permission = QJniObject(env->GetObjectArrayElement(permissions, i)).toString();
- auto value = results[i] == PERMISSION_GRANTED ?
- QtAndroidPrivate::PermissionsResult::Granted :
- QtAndroidPrivate::PermissionsResult::Denied;
- hash[permission] = value;
+ jobject activity = env->CallStaticObjectMethod(jQtNative, activityMethodID);
+ if (QJniEnvironment::checkAndClearExceptions(env))
+ return JNI_FALSE;
+
+ QWriteLocker locker(g_updateMutex());
+
+ if (g_jActivity) {
+ env->DeleteGlobalRef(g_jActivity);
+ g_jActivity = nullptr;
}
- QMetaObject::invokeMethod(request, "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash));
-}
-static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event)
-{
- jboolean ret = JNI_FALSE;
- QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
- for (auto *listener : qAsConst(g_genericMotionEventListeners()->listeners))
- ret |= listener->handleGenericMotionEvent(event);
- return ret;
-}
+ if (activity) {
+ g_jActivity = env->NewGlobalRef(activity);
+ env->DeleteLocalRef(activity);
+ }
-namespace {
- struct KeyEventListeners {
- QMutex mutex;
- QList<QtAndroidPrivate::KeyEventListener *> listeners;
- };
-}
-Q_GLOBAL_STATIC(KeyEventListeners, g_keyEventListeners)
+ env->DeleteLocalRef(jQtNative);
+ if (QJniEnvironment::checkAndClearExceptions(env))
+ return JNI_FALSE;
-static jboolean dispatchKeyEvent(JNIEnv *, jclass, jobject event)
-{
- jboolean ret = JNI_FALSE;
- QMutexLocker locker(&g_keyEventListeners()->mutex);
- for (auto *listener : qAsConst(g_keyEventListeners()->listeners))
- ret |= listener->handleKeyEvent(event);
- return ret;
+ return JNI_TRUE;
}
namespace {
@@ -288,89 +180,50 @@ void QtAndroidPrivate::handleResume()
listeners.at(i)->handleResume();
}
-static void setAndroidSdkVersion(JNIEnv *env)
-{
- jclass androidVersionClass = env->FindClass("android/os/Build$VERSION");
- if (QJniEnvironment::exceptionCheckAndClear(env))
- return;
-
- jfieldID androidSDKFieldID = env->GetStaticFieldID(androidVersionClass, "SDK_INT", "I");
- if (QJniEnvironment::exceptionCheckAndClear(env))
- return;
-
- g_androidSdkVersion = env->GetStaticIntField(androidVersionClass, androidSDKFieldID);
-}
-
-static void setNativeActivity(JNIEnv *env, jclass, jobject activity)
-{
- if (g_jActivity != 0)
- env->DeleteGlobalRef(g_jActivity);
-
- if (activity != 0) {
- g_jActivity = env->NewGlobalRef(activity);
- env->DeleteLocalRef(activity);
- } else {
- g_jActivity = 0;
- }
-}
-
-static void setNativeService(JNIEnv *env, jclass, jobject service)
-{
- if (g_jService != 0)
- env->DeleteGlobalRef(g_jService);
-
- if (service != 0) {
- g_jService = env->NewGlobalRef(service);
- env->DeleteLocalRef(service);
- } else {
- g_jService = 0;
- }
-}
-
jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
{
+ g_javaVM = vm;
+
jclass jQtNative = env->FindClass("org/qtproject/qt/android/QtNative");
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
jmethodID activityMethodID = env->GetStaticMethodID(jQtNative,
"activity",
"()Landroid/app/Activity;");
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
jobject activity = env->CallStaticObjectMethod(jQtNative, activityMethodID);
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
jmethodID serviceMethodID = env->GetStaticMethodID(jQtNative,
"service",
"()Landroid/app/Service;");
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
jobject service = env->CallStaticObjectMethod(jQtNative, serviceMethodID);
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
jmethodID classLoaderMethodID = env->GetStaticMethodID(jQtNative,
"classLoader",
"()Ljava/lang/ClassLoader;");
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
jobject classLoader = env->CallStaticObjectMethod(jQtNative, classLoaderMethodID);
- if (QJniEnvironment::exceptionCheckAndClear(env))
+ if (QJniEnvironment::checkAndClearExceptions(env))
return JNI_ERR;
- setAndroidSdkVersion(env);
-
g_jClassLoader = env->NewGlobalRef(classLoader);
env->DeleteLocalRef(classLoader);
if (activity) {
@@ -381,52 +234,61 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
g_jService = env->NewGlobalRef(service);
env->DeleteLocalRef(service);
}
- g_javaVM = vm;
static const JNINativeMethod methods[] = {
- {"runPendingCppRunnables", "()V", reinterpret_cast<void *>(runPendingCppRunnables)},
- {"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast<void *>(dispatchGenericMotionEvent)},
- {"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast<void *>(dispatchKeyEvent)},
- {"setNativeActivity", "(Landroid/app/Activity;)V", reinterpret_cast<void *>(setNativeActivity)},
- {"setNativeService", "(Landroid/app/Service;)V", reinterpret_cast<void *>(setNativeService)},
- {"sendRequestPermissionsResult", "(I[Ljava/lang/String;[I)V", reinterpret_cast<void *>(sendRequestPermissionsResult)},
+ {"updateNativeActivity", "()Z", reinterpret_cast<void *>(updateNativeActivity) },
};
const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
+ env->DeleteLocalRef(jQtNative);
+ if (!regOk && QJniEnvironment::checkAndClearExceptions(env))
+ return JNI_ERR;
- if (!regOk && QJniEnvironment::exceptionCheckAndClear(env))
+ QJniEnvironment qJniEnv;
+ if (!registerPermissionNatives(qJniEnv))
return JNI_ERR;
- g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
- "runPendingCppRunnablesOnAndroidThread",
- "()V");
- g_hideSplashScreenMethodID = env->GetStaticMethodID(jQtNative, "hideSplashScreen", "(I)V");
- g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative));
- env->DeleteLocalRef(jQtNative);
+ if (!registerNativeInterfaceNatives(qJniEnv))
+ return JNI_ERR;
+
+ if (!registerExtrasNatives(qJniEnv))
+ return JNI_ERR;
- qRegisterMetaType<QtAndroidPrivate::PermissionsHash>();
return JNI_OK;
}
+Q_CORE_EXPORT jobject qt_androidActivity()
+{
+ QReadLocker locker(g_updateMutex());
+ return g_jActivity;
+}
+
-jobject QtAndroidPrivate::activity()
+QtJniTypes::Activity QtAndroidPrivate::activity()
{
+ QReadLocker locker(g_updateMutex());
return g_jActivity;
}
-jobject QtAndroidPrivate::service()
+Q_CORE_EXPORT jobject qt_androidService()
{
return g_jService;
}
-jobject QtAndroidPrivate::context()
+QtJniTypes::Service QtAndroidPrivate::service()
{
+ return g_jService;
+}
+
+QtJniTypes::Context QtAndroidPrivate::context()
+{
+ QReadLocker locker(g_updateMutex());
if (g_jActivity)
return g_jActivity;
if (g_jService)
return g_jService;
- return 0;
+ return nullptr;
}
JavaVM *QtAndroidPrivate::javaVM()
@@ -441,178 +303,84 @@ jobject QtAndroidPrivate::classLoader()
jint QtAndroidPrivate::androidSdkVersion()
{
- return g_androidSdkVersion;
-}
-
-void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env)
-{
- runOnAndroidThread([runnable]() {
- runnable->run();
- if (runnable->autoDelete())
- delete runnable;
- }, env);
+ static jint sdkVersion = 0;
+ if (!sdkVersion)
+ sdkVersion = QJniObject::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT");
+ return sdkVersion;
}
-void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env)
+void QtAndroidPrivate::waitForServiceSetup()
{
- QMutexLocker locker(&g_pendingRunnablesMutex);
- const bool triggerRun = g_pendingRunnables->empty();
- g_pendingRunnables->push_back(runnable);
- locker.unlock();
- if (triggerRun)
- env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID);
+ g_waitForServiceSetupSemaphore->acquire();
}
-static bool waitForSemaphore(int timeoutMs, QSharedPointer<QSemaphore> sem)
+int QtAndroidPrivate::acuqireServiceSetup(int flags)
{
- while (timeoutMs > 0) {
- if (sem->tryAcquire(1, 10))
- return true;
- timeoutMs -= 10;
- QCoreApplication::processEvents();
- }
- return false;
+ g_serviceSetupLockers.ref();
+ return flags;
}
-void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env, int timeoutMs)
+void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *listener)
{
- QSharedPointer<QSemaphore> sem(new QSemaphore);
- runOnAndroidThread([&runnable, sem]{
- runnable();
- sem->release();
- }, env);
- waitForSemaphore(timeoutMs, sem);
+ const auto lock = qt_scoped_lock(g_onBindListenerMutex);
+ g_onBindListener = listener;
+ if (!g_serviceSetupLockers.deref())
+ g_waitForServiceSetupSemaphore->release();
}
-void QtAndroidPrivate::requestPermissions(JNIEnv *env,
- const QStringList &permissions,
- const QtAndroidPrivate::PermissionsResultFunc &callbackFunc,
- bool directCall)
+jobject QtAndroidPrivate::callOnBindListener(jobject intent)
{
- if (androidSdkVersion() < 23 || !activity()) {
- QHash<QString, QtAndroidPrivate::PermissionsResult> res;
- for (const auto &perm : permissions)
- res[perm] = checkPermission(perm);
- callbackFunc(res);
- return;
- }
- // Check API 23+ permissions
- const int requestCode = nextRequestCode();
- if (!directCall) {
- QMutexLocker locker(&g_pendingPermissionRequestsMutex);
- (*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
- }
-
- runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] {
- if (directCall) {
- QMutexLocker locker(&g_pendingPermissionRequestsMutex);
- (*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
- }
-
- QJniEnvironment env;
- jclass clazz = env->FindClass("java/lang/String");
-
- if (env.exceptionCheckAndClear())
- return;
-
- auto array = env->NewObjectArray(permissions.size(), clazz, nullptr);
- int index = 0;
- for (const auto &perm : permissions)
- env->SetObjectArrayElement(array, index++, QJniObject::fromString(perm).object());
- QJniObject(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
- env->DeleteLocalRef(array);
- }, env);
+ const auto lock = qt_scoped_lock(g_onBindListenerMutex);
+ if (g_onBindListener)
+ return g_onBindListener->onBind(intent);
+ return nullptr;
}
-QtAndroidPrivate::PermissionsHash QtAndroidPrivate::requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs)
-{
- QSharedPointer<QHash<QString, QtAndroidPrivate::PermissionsResult>> res(new QHash<QString, QtAndroidPrivate::PermissionsResult>());
- QSharedPointer<QSemaphore> sem(new QSemaphore);
- requestPermissions(env, permissions, [sem, res](const QHash<QString, PermissionsResult> &result){
- *res = result;
- sem->release();
- }, true);
- if (waitForSemaphore(timeoutMs, sem))
- return std::move(*res);
- else // mustn't touch *res
- return QHash<QString, QtAndroidPrivate::PermissionsResult>();
-}
+Q_CONSTINIT static QBasicAtomicInt g_androidDeadlockProtector = Q_BASIC_ATOMIC_INITIALIZER(0);
-QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)
+bool QtAndroidPrivate::acquireAndroidDeadlockProtector()
{
- const auto res = QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
- "checkSelfPermission",
- "(Ljava/lang/String;)I",
- QJniObject::fromString(permission).object());
- return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied;
+ return g_androidDeadlockProtector.testAndSetAcquire(0, 1);
}
-bool QtAndroidPrivate::shouldShowRequestPermissionRationale(const QString &permission)
+void QtAndroidPrivate::releaseAndroidDeadlockProtector()
{
- if (androidSdkVersion() < 23 || !activity())
- return false;
-
- return QJniObject(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale",
- "(Ljava/lang/String;)Z",
- QJniObject::fromString(permission).object());
+ g_androidDeadlockProtector.storeRelease(0);
}
-void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
-{
- QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
- g_genericMotionEventListeners()->listeners.push_back(listener);
-}
+QT_END_NAMESPACE
-void QtAndroidPrivate::unregisterGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
- QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
- g_genericMotionEventListeners()->listeners.removeOne(listener);
-}
+ Q_UNUSED(reserved);
-void QtAndroidPrivate::registerKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
-{
- QMutexLocker locker(&g_keyEventListeners()->mutex);
- g_keyEventListeners()->listeners.push_back(listener);
-}
+ static const char logTag[] = "QtCore";
+ static bool initialized = false;
+ if (initialized)
+ return JNI_VERSION_1_6;
+ initialized = true;
-void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
-{
- QMutexLocker locker(&g_keyEventListeners()->mutex);
- g_keyEventListeners()->listeners.removeOne(listener);
-}
+ typedef union {
+ JNIEnv *nenv;
+ void *venv;
+ } _JNIEnv;
-void QtAndroidPrivate::hideSplashScreen(JNIEnv *env, int duration)
-{
- env->CallStaticVoidMethod(g_jNativeClass, g_hideSplashScreenMethodID, duration);
-}
+ __android_log_print(ANDROID_LOG_INFO, logTag, "Start");
-void QtAndroidPrivate::waitForServiceSetup()
-{
- g_waitForServiceSetupSemaphore->acquire();
-}
+ _JNIEnv uenv;
+ uenv.venv = nullptr;
-int QtAndroidPrivate::acuqireServiceSetup(int flags)
-{
- g_serviceSetupLockers->ref();
- return flags;
-}
+ if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK) {
+ __android_log_print(ANDROID_LOG_FATAL, logTag, "GetEnv failed");
+ return JNI_ERR;
+ }
-void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *listener)
-{
- QMutexLocker lock(g_onBindListenerMutex());
- *g_onBindListener = listener;
- if (!g_serviceSetupLockers->deref())
- g_waitForServiceSetupSemaphore->release();
-}
+ JNIEnv *env = uenv.nenv;
+ const jint ret = QT_PREPEND_NAMESPACE(QtAndroidPrivate::initJNI(vm, env));
+ if (ret != 0) {
+ __android_log_print(ANDROID_LOG_FATAL, logTag, "initJNI failed");
+ return ret;
+ }
-jobject QtAndroidPrivate::callOnBindListener(jobject intent)
-{
- QMutexLocker lock(g_onBindListenerMutex());
- if (*g_onBindListener)
- return (*g_onBindListener)->onBind(intent);
- return nullptr;
+ return JNI_VERSION_1_6;
}
-
-QT_END_NAMESPACE
-
-#include "qjnihelpers.moc"