From fd1f0757919b6614a35275503d5d99095a4655fc Mon Sep 17 00:00:00 2001 From: Danny Wood Date: Fri, 24 May 2019 18:25:04 +0100 Subject: [PATCH] universal7580: camera: block calls to cancel_auto_focus for 1 second after camera2_auto_focus to workaround hard locks when it gets called too soon Change-Id: I8c274fb8de112ca279b98507a0d4ac2a2674da93 --- camera/Camera2Wrapper.cpp | 40 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/camera/Camera2Wrapper.cpp b/camera/Camera2Wrapper.cpp index d4dc35f..e105ae1 100644 --- a/camera/Camera2Wrapper.cpp +++ b/camera/Camera2Wrapper.cpp @@ -20,9 +20,25 @@ #define LOG_TAG "Camera2Wrapper" #include +#include + #include "CameraWrapper.h" #include "Camera2Wrapper.h" +#include + +/* current_timestamp() function from stack overflow: + * https://stackoverflow.com/questions/3756323/how-to-get-the-current-time-in-milliseconds-from-c-in-linux/17083824 + */ + +long long current_timestamp() { + struct timeval te; + gettimeofday(&te, NULL); // get current time + long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds + // printf("milliseconds: %lld\n", milliseconds); + return milliseconds; +} + typedef struct wrapper_camera2_device { camera_device_t base; int id; @@ -266,25 +282,45 @@ static void camera2_release_recording_frame(struct camera_device * device, VENDOR_CALL(device, release_recording_frame, opaque); } +long long CancelAFTimeGuard = 0; + static int camera2_auto_focus(struct camera_device * device) { + int Ret; ALOGV("%s->%08X->%08X", __FUNCTION__, (uintptr_t)device, (uintptr_t)(((wrapper_camera2_device_t*)device)->vendor)); if(!device) return -EINVAL; + /* Call the auto_focus function */ + Ret = VENDOR_CALL(device, auto_focus); + + /* Set the cancel_auto_focus time guard to now plus 1 second */ + CancelAFTimeGuard = current_timestamp() + 1000; - return VENDOR_CALL(device, auto_focus); + return Ret; } static int camera2_cancel_auto_focus(struct camera_device * device) { + int Ret; ALOGV("%s->%08X->%08X", __FUNCTION__, (uintptr_t)device, (uintptr_t)(((wrapper_camera2_device_t*)device)->vendor)); if(!device) return -EINVAL; - return VENDOR_CALL(device, cancel_auto_focus); + /* Calculate the difference between our guard time and now */ + long long TimeDiff = CancelAFTimeGuard - current_timestamp(); + /* Post a log message and return success (skipping the call) if the diff is greater than 0 */ + if(TimeDiff > 0) { + ALOGV("%s: CancelAFTimeGuard for %lli mS\n", __FUNCTION__, TimeDiff * 1000); + return 0; + } + + /* No active time guard so call the vendor function */ + Ret = VENDOR_CALL(device, cancel_auto_focus); + + return Ret; } static int camera2_take_picture(struct camera_device * device) -- 2.20.1