camera2: Fix video snapshot for HAL 2.* devices.

Bug: 15408128

- Lazily destroy ZSL stream when ZslProcessor is updated, or
  when the camera client is disconnected, allowing HAL 2.*
  devices that rely on the ZSL stream to capture video snapshots
  to function correctly.

Change-Id: Ia5cf14c62acda4d9c640440dc5b8e0796dc0b3fa
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 9d6ab23..e184d97 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -34,6 +34,7 @@
     api1/client2/JpegProcessor.cpp \
     api1/client2/CallbackProcessor.cpp \
     api1/client2/ZslProcessor.cpp \
+    api1/client2/ZslProcessorInterface.cpp \
     api1/client2/BurstCapture.cpp \
     api1/client2/JpegCompressor.cpp \
     api1/client2/CaptureSequencer.cpp \
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index bc40971..40c8e5d 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -434,6 +434,9 @@
     mCallbackProcessor->deleteStream();
     mZslProcessor->deleteStream();
 
+    // Remove all ZSL stream state before disconnect; needed to work around b/15408128.
+    mZslProcessor->disconnect();
+
     ALOGV("Camera %d: Disconnecting device", mCameraId);
 
     mDevice->disconnect();
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 8fb876e..bb72206 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -48,6 +48,7 @@
         mDevice(client->getCameraDevice()),
         mSequencer(sequencer),
         mId(client->getCameraId()),
+        mDeleted(false),
         mZslBufferAvailable(false),
         mZslStreamId(NO_STREAM),
         mZslReprocessStreamId(NO_STREAM),
@@ -62,7 +63,7 @@
 
 ZslProcessor::~ZslProcessor() {
     ALOGV("%s: Exit", __FUNCTION__);
-    deleteStream();
+    disconnect();
 }
 
 void ZslProcessor::onFrameAvailable() {
@@ -153,7 +154,7 @@
                     mId, strerror(-res), res);
             return res;
         }
-        if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
+        if (mDeleted || currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
                 currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
             res = device->deleteReprocessStream(mZslReprocessStreamId);
             if (res != OK) {
@@ -175,6 +176,8 @@
         }
     }
 
+    mDeleted = false;
+
     if (mZslStreamId == NO_STREAM) {
         // Create stream for HAL production
         // TODO: Sort out better way to select resolution for ZSL
@@ -209,6 +212,14 @@
 
 status_t ZslProcessor::deleteStream() {
     ATRACE_CALL();
+    Mutex::Autolock l(mInputMutex);
+    // WAR(b/15408128): do not delete stream unless client is being disconnected.
+    mDeleted = true;
+    return OK;
+}
+
+status_t ZslProcessor::disconnect() {
+    ATRACE_CALL();
     status_t res;
 
     Mutex::Autolock l(mInputMutex);
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h
index f4cf0c8..b6533cf 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h
@@ -67,6 +67,7 @@
 
     status_t updateStream(const Parameters &params);
     status_t deleteStream();
+    status_t disconnect();
     int getStreamId() const;
 
     status_t pushToReprocess(int32_t requestId);
@@ -86,6 +87,8 @@
     wp<CaptureSequencer> mSequencer;
     int mId;
 
+    bool mDeleted;
+
     mutable Mutex mInputMutex;
     bool mZslBufferAvailable;
     Condition mZslBufferAvailableSignal;
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp
new file mode 100644
index 0000000..9efeaba
--- /dev/null
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ZslProcessorInterface.h"
+
+namespace android {
+namespace camera2 {
+
+status_t ZslProcessorInterface::disconnect() {
+    return OK;
+}
+
+}; //namespace camera2
+}; //namespace android
+
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h
index 183c0c2..9e266e7 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessorInterface.h
@@ -19,6 +19,8 @@
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
 
 namespace android {
 namespace camera2 {
@@ -37,6 +39,9 @@
     // Delete the underlying CameraDevice streams
     virtual status_t deleteStream() = 0;
 
+    // Clear any additional state necessary before the CameraDevice is disconnected
+    virtual status_t disconnect();
+
     /**
      * Submits a ZSL capture request (id = requestId)
      *