Camera: Check for failing request ids when syncing with device

Capture requests especially those near the end of a capture session
can fail due to various reasons like Hal errors, invalid output
surfaces etc. Avoid possible timeouts when waiting for a request id
to return by checking the respective error notifications.

Bug: 159476108
Test: Legacy API Camera CTS
Change-Id: I84dedfbee1eeb0ff8cddf67fdb36c5dfafbb70ef
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index ebb0555..b043c0b 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -1777,6 +1777,14 @@
         case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
             ALOGW("%s: Received recoverable error %d from HAL - ignoring, requestId %" PRId32,
                     __FUNCTION__, errorCode, resultExtras.requestId);
+
+            if ((hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST == errorCode) ||
+                    (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT == errorCode)) {
+                Mutex::Autolock al(mLatestRequestMutex);
+
+                mLatestFailedRequestId = resultExtras.requestId;
+                mLatestRequestSignal.signal();
+            }
             mCaptureSequencer->notifyError(errorCode, resultExtras);
             return;
         default:
@@ -2303,7 +2311,7 @@
 
 status_t Camera2Client::waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout) {
     Mutex::Autolock l(mLatestRequestMutex);
-    while (mLatestRequestId != requestId) {
+    while ((mLatestRequestId != requestId) && (mLatestFailedRequestId != requestId)) {
         nsecs_t startTime = systemTime();
 
         auto res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
@@ -2312,7 +2320,7 @@
         timeout -= (systemTime() - startTime);
     }
 
-    return OK;
+    return (mLatestRequestId == requestId) ? OK : DEAD_OBJECT;
 }
 
 void Camera2Client::notifyRequestId(int32_t requestId) {
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 3144e0e..03ca44a 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -237,6 +237,7 @@
     mutable Mutex mLatestRequestMutex;
     Condition mLatestRequestSignal;
     int32_t mLatestRequestId = -1;
+    int32_t mLatestFailedRequestId = -1;
     status_t waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout);
     status_t waitUntilCurrentRequestIdLocked();
 };