diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/android/jar/src/org/qtproject/qt5/android/QtNative.java | 8 | ||||
-rw-r--r-- | src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java | 8 | ||||
-rw-r--r-- | src/corelib/kernel/qjnihelpers.cpp | 34 | ||||
-rw-r--r-- | src/corelib/kernel/qjnihelpers_p.h | 14 | ||||
-rw-r--r-- | src/plugins/platforms/android/androidjnimain.cpp | 17 |
5 files changed, 77 insertions, 4 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 92a7ec43e3..f15c7f3a97 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -51,11 +51,12 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ActivityInfo; import android.net.Uri; +import android.os.Build; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.content.ClipboardManager; import android.content.ClipboardManager.OnPrimaryClipChangedListener; -import android.os.Build; import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; @@ -908,4 +909,9 @@ public class QtNative private static native void setNativeActivity(Activity activity); private static native void setNativeService(Service service); + // activity methods + + // service methods + public static native IBinder onBind(Intent intent); + // service methods } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java index 035a65a84c..195ec376c9 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java @@ -53,6 +53,7 @@ import android.net.LocalSocket; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.ResultReceiver; import android.text.method.MetaKeyKeyListener; import android.util.Base64; @@ -187,4 +188,11 @@ public class QtServiceDelegate { QtNative.quitQtCoreApplication(); } + + public IBinder onBind(Intent intent) + { + synchronized (this) { + return QtNative.onBind(intent); + } + } } diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index dc60b0bc2b..02c58858ff 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -75,6 +75,11 @@ static jmethodID g_hideSplashScreenMethodID = Q_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_GLOBAL_STATIC(QSemaphore, g_waitForServiceSetupSemaphore); +Q_GLOBAL_STATIC(QAtomicInt, g_serviceSetupLockers); + class PermissionsResultClass : public QObject { Q_OBJECT @@ -511,7 +516,7 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis }, env); } -QHash<QString, QtAndroidPrivate::PermissionsResult> QtAndroidPrivate::requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs) +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); @@ -572,6 +577,33 @@ void QtAndroidPrivate::hideSplashScreen(JNIEnv *env, int duration) env->CallStaticVoidMethod(g_jNativeClass, g_hideSplashScreenMethodID, duration); } +void QtAndroidPrivate::waitForServiceSetup() +{ + g_waitForServiceSetupSemaphore->acquire(); +} + +int QtAndroidPrivate::acuqireServiceSetup(int flags) +{ + g_serviceSetupLockers->ref(); + return flags; +} + +void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *listener) +{ + QMutexLocker lock(g_onBindListenerMutex); + *g_onBindListener = listener; + if (!(*g_serviceSetupLockers)--) + g_waitForServiceSetupSemaphore->release(); +} + +jobject QtAndroidPrivate::callOnBindListener(jobject intent) +{ + QMutexLocker lock(g_onBindListenerMutex); + if (g_onBindListener) + return (*g_onBindListener)->onBind(intent); + return nullptr; +} + QT_END_NAMESPACE #include "qjnihelpers.moc" diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 7562d2c6f1..ea5103c173 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -100,6 +100,13 @@ namespace QtAndroidPrivate virtual bool handleKeyEvent(jobject event) = 0; }; + class Q_CORE_EXPORT OnBindListener + { + public: + virtual ~OnBindListener() {} + virtual jobject onBind(jobject intent) = 0; + }; + enum class PermissionsResult { Granted, Denied @@ -143,6 +150,13 @@ namespace QtAndroidPrivate Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener); Q_CORE_EXPORT void hideSplashScreen(JNIEnv *env, int duration = 0); + + + Q_CORE_EXPORT void waitForServiceSetup(); + Q_CORE_EXPORT int acuqireServiceSetup(int flags); + Q_CORE_EXPORT void setOnBindListener(OnBindListener *listener); + Q_CORE_EXPORT jobject callOnBindListener(jobject intent); + } QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 06bca0354d..4a24f3fb47 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -542,7 +542,14 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para if (sem_init(&m_terminateSemaphore, 0, 0) == -1) return false; - return pthread_create(&m_qtAppThread, nullptr, startMainMethod, nullptr) == 0; + jboolean res = pthread_create(&m_qtAppThread, nullptr, startMainMethod, nullptr) == 0; + + // The service must wait until the QCoreApplication starts otherwise onBind will be + // called too early + if (m_serviceObject) + QtAndroidPrivate::waitForServiceSetup(); + + return res; } static void quitQtCoreApplication(JNIEnv *env, jclass /*clazz*/) @@ -742,6 +749,11 @@ static void onNewIntent(JNIEnv *env, jclass /*cls*/, jobject data) QtAndroidPrivate::handleNewIntent(env, data); } +static jobject onBind(JNIEnv */*env*/, jclass /*cls*/, jobject intent) +{ + return QtAndroidPrivate::callOnBindListener(intent); +} + static JNINativeMethod methods[] = { {"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin}, {"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication}, @@ -754,7 +766,8 @@ static JNINativeMethod methods[] = { {"updateApplicationState", "(I)V", (void *)updateApplicationState}, {"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}, {"onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult}, - {"onNewIntent", "(Landroid/content/Intent;)V", (void *)onNewIntent} + {"onNewIntent", "(Landroid/content/Intent;)V", (void *)onNewIntent}, + {"onBind", "(Landroid/content/Intent;)Landroid/os/IBinder;", (void *)onBind} }; #define FIND_AND_CHECK_CLASS(CLASS_NAME) \ |