summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorBogDan Vatra <bogdan@kdab.com>2016-02-17 14:37:50 +0200
committerBogDan Vatra <bogdan@kdab.com>2016-02-17 14:29:58 +0000
commitefcf1dec4992bf7aab5bf1f0f4c0ee8c54030465 (patch)
tree5c46f66065750007a5dafdf7ca394af6f33c2b82 /src/plugins
parent4a7ccf74ff85a49e8c701a4d1c40f316b6fec4c5 (diff)
Say hello to Android Services
This changeset enables running a QCoreApplication from within an Android Service. The Android Application running can now have a QtActivity or a QtService, but having both in the same process is not supported. This patch was based on Cory Slep's patch [ChangeLog][Android] Qt can now be used to easily create Android Services. Task-number: QTBUG-37221 Change-Id: I0fd693daaa85b991940ffe9cc41c483022677199 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp23
-rw-r--r--src/plugins/platforms/android/androidjnimain.h1
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp27
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidsystemlocale.cpp2
5 files changed, 41 insertions, 14 deletions
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 1eae295724..6340d47c18 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -78,6 +78,7 @@ static AAssetManager *m_assetManager = nullptr;
static jobject m_resourcesObj = nullptr;
static jobject m_activityObject = nullptr;
static jmethodID m_createSurfaceMethodID = nullptr;
+static jobject m_serviceObject = nullptr;
static jmethodID m_setSurfaceGeometryMethodID = nullptr;
static jmethodID m_destroySurfaceMethodID = nullptr;
@@ -193,6 +194,11 @@ namespace QtAndroid
return m_activityObject;
}
+ jobject service()
+ {
+ return m_serviceObject;
+ }
+
void showStatusBar()
{
if (m_statusBarShowing)
@@ -534,7 +540,6 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
return pthread_create(&m_qtAppThread, nullptr, startMainMethod, nullptr) == 0;
}
-
static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
{
Q_UNUSED(env);
@@ -553,6 +558,8 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
env->DeleteGlobalRef(m_resourcesObj);
if (m_activityObject)
env->DeleteGlobalRef(m_activityObject);
+ if (m_serviceObject)
+ env->DeleteGlobalRef(m_serviceObject);
if (m_bitmapClass)
env->DeleteGlobalRef(m_bitmapClass);
if (m_ARGB_8888_BitmapConfigValue)
@@ -785,20 +792,26 @@ static int registerNatives(JNIEnv *env)
jmethodID methodID;
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
+ GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "service", "()Landroid/app/Service;");
+ jobject serviceObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "classLoader", "()Ljava/lang/ClassLoader;");
m_classLoaderObject = env->NewGlobalRef(env->CallStaticObjectMethod(m_applicationClass, methodID));
clazz = env->GetObjectClass(m_classLoaderObject);
GET_AND_CHECK_METHOD(m_loadClassMethodID, clazz, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+ if (serviceObject)
+ m_serviceObject = env->NewGlobalRef(serviceObject);
- if (activityObject) {
+ if (activityObject)
m_activityObject = env->NewGlobalRef(activityObject);
+ jobject object = activityObject ? activityObject : serviceObject;
+ if (object) {
FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
- m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID));
+ m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(object, methodID));
GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
- m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID));
+ m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(object, methodID));
FIND_AND_CHECK_CLASS("android/graphics/Bitmap");
m_bitmapClass = static_cast<jclass>(env->NewGlobalRef(clazz));
@@ -819,8 +832,6 @@ static int registerNatives(JNIEnv *env)
"(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V");
}
-
-
return JNI_TRUE;
}
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index e3c18b2e7a..218e52ccc1 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -83,6 +83,7 @@ namespace QtAndroid
AAssetManager *assetManager();
jclass applicationClass();
jobject activity();
+ jobject service();
void setApplicationActive();
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 1f8ee79396..80d7e31aa3 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -66,7 +66,6 @@
#include "qandroidplatformtheme.h"
#include "qandroidsystemlocale.h"
-
QT_BEGIN_NAMESPACE
int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
@@ -87,6 +86,8 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
return QtAndroid::javaVM();
if (resource == "QtActivity")
return QtAndroid::activity();
+ if (resource == "QtService")
+ return QtAndroid::service();
if (resource == "AndroidStyleData") {
if (m_androidStyle) {
if (m_androidStyle->m_styleData.isEmpty())
@@ -122,7 +123,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
#endif
{
Q_UNUSED(paramList);
-
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -159,6 +159,9 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
#endif // QT_NO_ACCESSIBILITY
QJNIObjectPrivate javaActivity(QtAndroid::activity());
+ if (!javaActivity.isValid())
+ javaActivity = QtAndroid::service();
+
if (javaActivity.isValid()) {
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
@@ -205,13 +208,13 @@ static bool needsBasicRenderloopWorkaround()
bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
{
switch (cap) {
- case ThreadedPixmaps: return true;
case ApplicationState: return true;
- case NativeWidgets: return true;
- case OpenGL: return true;
- case ForeignWindows: return true;
- case ThreadedOpenGL: return !needsBasicRenderloopWorkaround();
- case RasterGLSurface: return true;
+ case ThreadedPixmaps: return true;
+ case NativeWidgets: return QtAndroid::activity();
+ case OpenGL: return QtAndroid::activity();
+ case ForeignWindows: return QtAndroid::activity();
+ case ThreadedOpenGL: return !needsBasicRenderloopWorkaround() && QtAndroid::activity();
+ case RasterGLSurface: return QtAndroid::activity();
default:
return QPlatformIntegration::hasCapability(cap);
}
@@ -219,11 +222,15 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(QWindow *window) const
{
+ if (!QtAndroid::activity())
+ return nullptr;
return new QAndroidPlatformBackingStore(window);
}
QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
+ if (!QtAndroid::activity())
+ return nullptr;
QSurfaceFormat format(context->format());
format.setAlphaBufferSize(8);
format.setRedBufferSize(8);
@@ -234,6 +241,8 @@ QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext
QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
+ if (!QtAndroid::activity())
+ return nullptr;
QSurfaceFormat format(surface->requestedFormat());
format.setAlphaBufferSize(8);
format.setRedBufferSize(8);
@@ -245,6 +254,8 @@ QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenS
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
+ if (!QtAndroid::activity())
+ return nullptr;
if (window->type() == Qt::ForeignWindow)
return new QAndroidPlatformForeignWindow(window);
else
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index dd29c29bab..aa4fa94f0a 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -294,6 +294,8 @@ int QAndroidPlatformScreen::rasterSurfaces()
void QAndroidPlatformScreen::doRedraw()
{
PROFILE_SCOPE;
+ if (!QtAndroid::activity())
+ return;
if (m_dirtyRect.isEmpty())
return;
diff --git a/src/plugins/platforms/android/qandroidsystemlocale.cpp b/src/plugins/platforms/android/qandroidsystemlocale.cpp
index 1528d90d06..7fe36aa9bc 100644
--- a/src/plugins/platforms/android/qandroidsystemlocale.cpp
+++ b/src/plugins/platforms/android/qandroidsystemlocale.cpp
@@ -56,6 +56,8 @@ void QAndroidSystemLocale::getLocaleFromJava() const
QJNIObjectPrivate javaLocaleObject;
QJNIObjectPrivate javaActivity(QtAndroid::activity());
+ if (!javaActivity.isValid())
+ javaActivity = QtAndroid::service();
if (javaActivity.isValid()) {
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");