summaryrefslogtreecommitdiffstats
path: root/src/plugins/android/src/wrappers/jni/androidcamera.cpp
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@digia.com>2014-07-10 16:56:23 +0200
committerChristian Stromme <christian.stromme@digia.com>2014-07-14 01:59:35 +0200
commita7d10a265aea417ed80f9cf90545b4c3b6cd8866 (patch)
treeffac173e3b03eb8d5702c6586b5011c12d188aed /src/plugins/android/src/wrappers/jni/androidcamera.cpp
parent389d66b3ed5e2d798e9fb124064523239c393ad8 (diff)
Android: Make sure we check and clear exceptions from the camera.
In several places we where ignoring the fact that we might get an exception from the camera code on Android. Failing to clear them will cause the application to to terminate. Task-number: QTBUG-39425 Change-Id: Idfe40e1749f54d551d37dae25912d9ddbc3da01e Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src/plugins/android/src/wrappers/jni/androidcamera.cpp')
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.cpp80
1 files changed, 51 insertions, 29 deletions
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
index c917bf2b7..32fc4bbaf 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
@@ -56,6 +56,19 @@ static QMutex g_cameraMapMutex;
typedef QMap<int, AndroidCamera *> CameraMap;
Q_GLOBAL_STATIC(CameraMap, g_cameraMap)
+static inline bool exceptionCheckAndClear(JNIEnv *env)
+{
+ if (Q_UNLIKELY(env->ExceptionCheck())) {
+#ifdef QT_DEBUG
+ env->ExceptionDescribe();
+#endif // QT_DEBUG
+ env->ExceptionClear();
+ return true;
+ }
+
+ return false;
+}
+
static QRect areaToRect(jobject areaObj)
{
QJNIObjectPrivate area(areaObj);
@@ -132,9 +145,9 @@ public:
Q_INVOKABLE bool init(int cameraId);
Q_INVOKABLE void release();
- Q_INVOKABLE void lock();
- Q_INVOKABLE void unlock();
- Q_INVOKABLE void reconnect();
+ Q_INVOKABLE bool lock();
+ Q_INVOKABLE bool unlock();
+ Q_INVOKABLE bool reconnect();
Q_INVOKABLE AndroidCamera::CameraFacing getFacing();
Q_INVOKABLE int getNativeOrientation();
@@ -147,7 +160,7 @@ public:
Q_INVOKABLE QSize previewSize() const { return m_previewSize; }
Q_INVOKABLE void updatePreviewSize();
- Q_INVOKABLE void setPreviewTexture(void *surfaceTexture);
+ Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture);
Q_INVOKABLE bool isZoomSupported();
Q_INVOKABLE int getMaxZoom();
@@ -266,7 +279,7 @@ AndroidCamera *AndroidCamera::open(int cameraId)
worker->start();
d->moveToThread(worker);
connect(worker, &QThread::finished, d, &AndroidCameraPrivate::deleteLater);
- bool ok = false;
+ bool ok = true;
QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId));
if (!ok) {
worker->quit();
@@ -289,22 +302,28 @@ int AndroidCamera::cameraId() const
return d->m_cameraId;
}
-void AndroidCamera::lock()
+bool AndroidCamera::lock()
{
Q_D(AndroidCamera);
- QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection);
+ bool ok = true;
+ QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok));
+ return ok;
}
-void AndroidCamera::unlock()
+bool AndroidCamera::unlock()
{
Q_D(AndroidCamera);
- QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection);
+ bool ok = true;
+ QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok));
+ return ok;
}
-void AndroidCamera::reconnect()
+bool AndroidCamera::reconnect()
{
Q_D(AndroidCamera);
- QMetaObject::invokeMethod(d, "reconnect");
+ bool ok = true;
+ QMetaObject::invokeMethod(d, "reconnect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok));
+ return ok;
}
void AndroidCamera::release()
@@ -368,13 +387,16 @@ void AndroidCamera::setPreviewSize(const QSize &size)
QMetaObject::invokeMethod(d, "updatePreviewSize");
}
-void AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
+bool AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
{
Q_D(AndroidCamera);
+ bool ok = true;
QMetaObject::invokeMethod(d,
"setPreviewTexture",
Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, ok),
Q_ARG(void *, surfaceTexture ? surfaceTexture->surfaceTexture() : 0));
+ return ok;
}
bool AndroidCamera::isZoomSupported()
@@ -698,12 +720,12 @@ AndroidCameraPrivate::~AndroidCameraPrivate()
bool AndroidCameraPrivate::init(int cameraId)
{
m_cameraId = cameraId;
+ QJNIEnvironmentPrivate env;
m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera",
"open",
"(I)Landroid/hardware/Camera;",
cameraId);
-
- if (!m_camera.isValid())
+ if (exceptionCheckAndClear(env) || !m_camera.isValid())
return false;
m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId);
@@ -731,26 +753,25 @@ void AndroidCameraPrivate::release()
m_camera.callMethod<void>("release");
}
-void AndroidCameraPrivate::lock()
+bool AndroidCameraPrivate::lock()
{
+ QJNIEnvironmentPrivate env;
m_camera.callMethod<void>("lock");
+ return !exceptionCheckAndClear(env);
}
-void AndroidCameraPrivate::unlock()
+bool AndroidCameraPrivate::unlock()
{
+ QJNIEnvironmentPrivate env;
m_camera.callMethod<void>("unlock");
+ return !exceptionCheckAndClear(env);
}
-void AndroidCameraPrivate::reconnect()
+bool AndroidCameraPrivate::reconnect()
{
QJNIEnvironmentPrivate env;
m_camera.callMethod<void>("reconnect");
- if (env->ExceptionCheck()) {
-#ifdef QT_DEBUG
- env->ExceptionDescribe();
-#endif // QT_DEBUG
- env->ExceptionDescribe();
- }
+ return !exceptionCheckAndClear(env);
}
AndroidCamera::CameraFacing AndroidCameraPrivate::getFacing()
@@ -832,11 +853,13 @@ void AndroidCameraPrivate::updatePreviewSize()
emit previewSizeChanged();
}
-void AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture)
+bool AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture)
{
+ QJNIEnvironmentPrivate env;
m_camera.callMethod<void>("setPreviewTexture",
"(Landroid/graphics/SurfaceTexture;)V",
static_cast<jobject>(surfaceTexture));
+ return !exceptionCheckAndClear(env);
}
bool AndroidCameraPrivate::isZoomSupported()
@@ -1020,8 +1043,7 @@ void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
arrayList.callMethod<jboolean>("add",
"(Ljava/lang/Object;)Z",
rectToArea(areas.at(i)).object());
- if (env->ExceptionCheck())
- env->ExceptionClear();
+ exceptionCheckAndClear(env);
}
list = arrayList;
}
@@ -1347,9 +1369,11 @@ void AndroidCameraPrivate::fetchLastPreviewFrame()
void AndroidCameraPrivate::applyParameters()
{
+ QJNIEnvironmentPrivate env;
m_camera.callMethod<void>("setParameters",
"(Landroid/hardware/Camera$Parameters;)V",
m_parameters.object());
+ exceptionCheckAndClear(env);
}
QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArray &methodName)
@@ -1386,10 +1410,8 @@ static JNINativeMethod methods[] = {
bool AndroidCamera::initJNI(JNIEnv *env)
{
jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener");
- if (env->ExceptionCheck())
- env->ExceptionClear();
- if (clazz) {
+ if (!exceptionCheckAndClear(env) && clazz) {
g_qtCameraListenerClass = static_cast<jclass>(env->NewGlobalRef(clazz));
if (env->RegisterNatives(g_qtCameraListenerClass,
methods,