Forward Service.onBind notification to Qt
It is needed to implement Android Binder in Qt. Change-Id: I8f6f8ef778f97a444a1b16d6f62e211e188b65cc Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
cfbe03a6e0
commit
4f7507c523
@ -51,11 +51,12 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.ClipboardManager.OnPrimaryClipChangedListener;
|
import android.content.ClipboardManager.OnPrimaryClipChangedListener;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -908,4 +909,9 @@ public class QtNative
|
|||||||
|
|
||||||
private static native void setNativeActivity(Activity activity);
|
private static native void setNativeActivity(Activity activity);
|
||||||
private static native void setNativeService(Service service);
|
private static native void setNativeService(Service service);
|
||||||
|
// activity methods
|
||||||
|
|
||||||
|
// service methods
|
||||||
|
public static native IBinder onBind(Intent intent);
|
||||||
|
// service methods
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ import android.net.LocalSocket;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
import android.text.method.MetaKeyKeyListener;
|
import android.text.method.MetaKeyKeyListener;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
@ -187,4 +188,11 @@ public class QtServiceDelegate
|
|||||||
{
|
{
|
||||||
QtNative.quitQtCoreApplication();
|
QtNative.quitQtCoreApplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IBinder onBind(Intent intent)
|
||||||
|
{
|
||||||
|
synchronized (this) {
|
||||||
|
return QtNative.onBind(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,11 @@ static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR;
|
|||||||
Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
|
Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
|
||||||
static QBasicMutex g_pendingRunnablesMutex;
|
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
|
class PermissionsResultClass : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -511,7 +516,7 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis
|
|||||||
}, env);
|
}, 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<QHash<QString, QtAndroidPrivate::PermissionsResult>> res(new QHash<QString, QtAndroidPrivate::PermissionsResult>());
|
||||||
QSharedPointer<QSemaphore> sem(new QSemaphore);
|
QSharedPointer<QSemaphore> sem(new QSemaphore);
|
||||||
@ -572,6 +577,33 @@ void QtAndroidPrivate::hideSplashScreen(JNIEnv *env, int duration)
|
|||||||
env->CallStaticVoidMethod(g_jNativeClass, g_hideSplashScreenMethodID, 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
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "qjnihelpers.moc"
|
#include "qjnihelpers.moc"
|
||||||
|
@ -100,6 +100,13 @@ namespace QtAndroidPrivate
|
|||||||
virtual bool handleKeyEvent(jobject event) = 0;
|
virtual bool handleKeyEvent(jobject event) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Q_CORE_EXPORT OnBindListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~OnBindListener() {}
|
||||||
|
virtual jobject onBind(jobject intent) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
enum class PermissionsResult {
|
enum class PermissionsResult {
|
||||||
Granted,
|
Granted,
|
||||||
Denied
|
Denied
|
||||||
@ -143,6 +150,13 @@ namespace QtAndroidPrivate
|
|||||||
Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
|
Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
|
||||||
|
|
||||||
Q_CORE_EXPORT void hideSplashScreen(JNIEnv *env, int duration = 0);
|
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
|
QT_END_NAMESPACE
|
||||||
|
@ -542,7 +542,14 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
|
|||||||
if (sem_init(&m_terminateSemaphore, 0, 0) == -1)
|
if (sem_init(&m_terminateSemaphore, 0, 0) == -1)
|
||||||
return false;
|
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*/)
|
static void quitQtCoreApplication(JNIEnv *env, jclass /*clazz*/)
|
||||||
@ -742,6 +749,11 @@ static void onNewIntent(JNIEnv *env, jclass /*cls*/, jobject data)
|
|||||||
QtAndroidPrivate::handleNewIntent(env, data);
|
QtAndroidPrivate::handleNewIntent(env, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jobject onBind(JNIEnv */*env*/, jclass /*cls*/, jobject intent)
|
||||||
|
{
|
||||||
|
return QtAndroidPrivate::callOnBindListener(intent);
|
||||||
|
}
|
||||||
|
|
||||||
static JNINativeMethod methods[] = {
|
static JNINativeMethod methods[] = {
|
||||||
{"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
|
{"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
|
||||||
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
|
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
|
||||||
@ -754,7 +766,8 @@ static JNINativeMethod methods[] = {
|
|||||||
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
|
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
|
||||||
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged},
|
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged},
|
||||||
{"onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult},
|
{"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) \
|
#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user