Camera: Stop repeating request if its output is abandoned

Stop repeating request if any of its output stream is abandoned.
Add a callback to notify the repeating request has been stopped
with frame number of the last frame.

Update NDK with the new callback and behavior.

Bug: 21270879

Change-Id: I3553775c7807a77104aa1650609480ca3321310c
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index e395935..0de80bd 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2807,6 +2807,11 @@
 
 status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
     Mutex::Autolock l(mRequestLock);
+    return clearRepeatingRequestsLocked(lastFrameNumber);
+
+}
+
+status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
     mRepeatingRequests.clear();
     if (lastFrameNumber != NULL) {
         *lastFrameNumber = mRepeatingLastFrameNumber;
@@ -2961,6 +2966,22 @@
     }
 }
 
+void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
+    Mutex::Autolock l(mRequestLock);
+    // Check all streams needed by repeating requests are still valid. Otherwise, stop
+    // repeating requests.
+    for (const auto& request : mRepeatingRequests) {
+        for (const auto& s : request->mOutputStreams) {
+            if (s->isAbandoned()) {
+                int64_t lastFrameNumber = 0;
+                clearRepeatingRequestsLocked(&lastFrameNumber);
+                mListener->notifyRepeatingRequestError(lastFrameNumber);
+                return;
+            }
+        }
+    }
+}
+
 bool Camera3Device::RequestThread::threadLoop() {
     ATRACE_CALL();
     status_t res;
@@ -2992,6 +3013,8 @@
     if (res == TIMED_OUT) {
         // Not a fatal error if getting output buffers time out.
         cleanUpFailedRequests(/*sendRequestError*/ true);
+        // Check if any stream is abandoned.
+        checkAndStopRepeatingRequest();
         return true;
     } else if (res != OK) {
         cleanUpFailedRequests(/*sendRequestError*/ false);