Merge "Camera2: State must be STOPPED before JPEG callback is fired." into jb-mr1-dev
diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
index 24ecf28..941ad15 100644
--- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
@@ -96,11 +96,13 @@
     }
 }
 
-void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp) {
+void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
+        sp<MemoryBase> captureBuffer) {
     ATRACE_CALL();
     ALOGV("%s", __FUNCTION__);
     Mutex::Autolock l(mInputMutex);
     mCaptureTimestamp = timestamp;
+    mCaptureBuffer = captureBuffer;
     if (!mNewCaptureReceived) {
         mNewCaptureReceived = true;
         mNewCaptureSignal.signal();
@@ -195,7 +197,7 @@
 }
 
 CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
-    status_t res;
+    status_t res = OK;
     ATRACE_CALL();
     mCaptureId++;
 
@@ -204,20 +206,34 @@
         mBusy = false;
     }
 
-    SharedParameters::Lock l(client->getParameters());
-    switch (l.mParameters.state) {
-        case Parameters::STILL_CAPTURE:
-            l.mParameters.state = Parameters::STOPPED;
-            break;
-        case Parameters::VIDEO_SNAPSHOT:
-            l.mParameters.state = Parameters::RECORD;
-            break;
-        default:
-            ALOGE("%s: Camera %d: Still image produced unexpectedly "
-                    "in state %s!",
-                    __FUNCTION__, client->getCameraId(),
-                    Parameters::getStateName(l.mParameters.state));
+    {
+        SharedParameters::Lock l(client->getParameters());
+        switch (l.mParameters.state) {
+            case Parameters::STILL_CAPTURE:
+                l.mParameters.state = Parameters::STOPPED;
+                break;
+            case Parameters::VIDEO_SNAPSHOT:
+                l.mParameters.state = Parameters::RECORD;
+                break;
+            default:
+                ALOGE("%s: Camera %d: Still image produced unexpectedly "
+                        "in state %s!",
+                        __FUNCTION__, client->getCameraId(),
+                        Parameters::getStateName(l.mParameters.state));
+                res = INVALID_OPERATION;
+        }
     }
+    if (mCaptureBuffer != 0 && res == OK) {
+        Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
+        ALOGV("%s: Sending still image to client", __FUNCTION__);
+        if (l.mCameraClient != 0) {
+            l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
+                    mCaptureBuffer, NULL);
+        } else {
+            ALOGV("%s: No client!", __FUNCTION__);
+        }
+    }
+    mCaptureBuffer.clear();
 
     return IDLE;
 }
diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.h b/services/camera/libcameraservice/camera2/CaptureSequencer.h
index 474bdac..f0d1e79 100644
--- a/services/camera/libcameraservice/camera2/CaptureSequencer.h
+++ b/services/camera/libcameraservice/camera2/CaptureSequencer.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SERVERS_CAMERA_CAMERA2_CAPTURESEQUENCER_H
 #define ANDROID_SERVERS_CAMERA_CAMERA2_CAPTURESEQUENCER_H
 
+#include <binder/MemoryBase.h>
 #include <utils/Thread.h>
 #include <utils/String16.h>
 #include <utils/Vector.h>
@@ -58,8 +59,8 @@
     // Notifications from the frame processor
     virtual void onFrameAvailable(int32_t frameId, CameraMetadata &frame);
 
-    // Notifications from the capture processor
-    void onCaptureAvailable(nsecs_t timestamp);
+    // Notifications from the JPEG processor
+    void onCaptureAvailable(nsecs_t timestamp, sp<MemoryBase> captureBuffer);
 
     void dump(int fd, const Vector<String16>& args);
 
@@ -85,6 +86,7 @@
 
     bool mNewCaptureReceived;
     nsecs_t mCaptureTimestamp;
+    sp<MemoryBase> mCaptureBuffer;
     Condition mNewCaptureSignal;
 
     /**
diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.cpp b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
index b230d2d..7ab9c87 100644
--- a/services/camera/libcameraservice/camera2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
@@ -230,11 +230,6 @@
         return OK;
     }
 
-    sp<CaptureSequencer> sequencer = mSequencer.promote();
-    if (sequencer != 0) {
-        sequencer->onCaptureAvailable(imgBuffer.timestamp);
-    }
-
     // TODO: Optimize this to avoid memcopy
     void* captureMemory = mCaptureHeap->mHeap->getBase();
     size_t size = mCaptureHeap->mHeap->getSize();
@@ -242,16 +237,11 @@
 
     mCaptureConsumer->unlockBuffer(imgBuffer);
 
-    captureHeap = mCaptureHeap;
-
-    Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
-    ALOGV("%s: Sending still image to client", __FUNCTION__);
-    if (l.mCameraClient != 0) {
-        l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
-                captureHeap->mBuffers[0], NULL);
-    } else {
-        ALOGV("%s: No client!", __FUNCTION__);
+    sp<CaptureSequencer> sequencer = mSequencer.promote();
+    if (sequencer != 0) {
+        sequencer->onCaptureAvailable(imgBuffer.timestamp, mCaptureHeap->mBuffers[0]);
     }
+
     return OK;
 }