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.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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
Loading…
x
Reference in New Issue
Block a user