From 95e1012c9dc49e0afbed52d17ff32a4a59a723f7 Mon Sep 17 00:00:00 2001
From: Yoann Lopes <yoann.lopes@qt.io>
Date: Wed, 13 Jul 2016 11:15:45 +0200
Subject: [PATCH] Android: fix freeze when taking pictures on some devices

On some devices and on the emulator, the preview callback must be
cleared before taking a picture to avoid a camera server freeze.

Task-number: QTBUG-54709
Change-Id: I9e4ad417fa08cddea7edfd232f5b5df40ada59ee
Reviewed-by: Christian Stromme <christian.stromme@qt.io>
---
 .../qtproject/qt5/android/multimedia/QtCameraListener.java | 7 ++++++-
 src/plugins/android/src/wrappers/jni/androidcamera.cpp     | 5 +++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java
index 008458e89..8a2697afe 100644
--- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java
+++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java
@@ -104,11 +104,16 @@ public class QtCameraListener implements Camera.ShutterCallback,
         return m_previewBytesPerLine;
     }
 
+    public void clearPreviewCallback(Camera camera)
+    {
+        camera.setPreviewCallbackWithBuffer(null);
+    }
+
     public void setupPreviewCallback(Camera camera)
     {
         // Clear previous callback (also clears added buffers)
+        clearPreviewCallback(camera);
         m_lastPreviewBuffer = null;
-        camera.setPreviewCallbackWithBuffer(null);
 
         final Camera.Parameters params = camera.getParameters();
         m_previewSize = params.getPreviewSize();
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
index 0ce8eff39..b0e02b7c2 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
@@ -1436,6 +1436,11 @@ void AndroidCameraPrivate::takePicture()
 {
     QJNIEnvironmentPrivate env;
 
+    // We must clear the preview callback before calling takePicture(), otherwise the call will
+    // block and the camera server will be frozen until the next device restart...
+    // That problem only happens on some devices and on the emulator
+    m_cameraListener.callMethod<void>("clearPreviewCallback", "(Landroid/hardware/Camera;)V", m_camera.object());
+
     m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;"
                                              "Landroid/hardware/Camera$PictureCallback;"
                                              "Landroid/hardware/Camera$PictureCallback;)V",
-- 
GitLab