Camera: Pause preview when needing to delete jpeg/zsl streams

Bug: 8876221
Change-Id: Idf9490a48462fa44d49c4ebe99425c3149ae6378
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 48f3606..2e01dae 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -690,7 +690,7 @@
         outputStreams.push(getCallbackStreamId());
     }
     if (params.zslMode && !params.recordingHint) {
-        res = mZslProcessor->updateStream(params);
+        res = updateProcessorStream(mZslProcessor, params);
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to update ZSL stream: %s (%d)",
                     __FUNCTION__, mCameraId, strerror(-res), res);
@@ -718,7 +718,7 @@
         // assumption that the user will record video. To optimize recording
         // startup time, create the necessary output streams for recording and
         // video snapshot now if they don't already exist.
-        res = mJpegProcessor->updateStream(params);
+        res = updateProcessorStream(mJpegProcessor, params);
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't pre-configure still image "
                     "stream: %s (%d)",
@@ -1125,7 +1125,7 @@
 
         ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
 
-        res = mJpegProcessor->updateStream(l.mParameters);
+        res = updateProcessorStream(mJpegProcessor, l.mParameters);
         if (res != OK) {
             ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
                     __FUNCTION__, mCameraId, strerror(-res), res);
@@ -1605,5 +1605,47 @@
     return res;
 }
 
+template <typename ProcessorT>
+status_t Camera2Client::updateProcessorStream(sp<ProcessorT> processor,
+                                              camera2::Parameters params) {
+    status_t res;
+
+    res = processor->updateStream(params);
+
+    /**
+     * Can't update the stream if it's busy?
+     *
+     * Then we need to stop the device (by temporarily clearing the request
+     * queue) and then try again. Resume streaming once we're done.
+     */
+    if (res == -EBUSY) {
+        res = mStreamingProcessor->togglePauseStream(/*pause*/true);
+        if (res != OK) {
+            ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)",
+                    __FUNCTION__, mCameraId, strerror(-res), res);
+        }
+
+        res = mDevice->waitUntilDrained();
+        if (res != OK) {
+            ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
+                    __FUNCTION__, mCameraId, strerror(-res), res);
+        }
+
+        res = processor->updateStream(params);
+        if (res != OK) {
+            ALOGE("%s: Camera %d: Failed to update processing stream "
+                  " despite having halted streaming first: %s (%d)",
+                  __FUNCTION__, mCameraId, strerror(-res), res);
+        }
+
+        res = mStreamingProcessor->togglePauseStream(/*pause*/false);
+        if (res != OK) {
+            ALOGE("%s: Camera %d: Can't unpause streaming: %s (%d)",
+                    __FUNCTION__, mCameraId, strerror(-res), res);
+        }
+    }
+
+    return res;
+}
 
 } // namespace android