CameraService: trigger appropriate callbacks for burst capture.

* Instead of tracking CameraMetadata only, now we track both
CameraMetadata and CaptureResultExtras, which is not part of
the HAL metadata. This will enable the correct callback of
onCaptureStarted and onResultReceived given burst requests.

* Get last frame number in reply when submitting requests,
canceling requests, and flushing device. For repeating requests,
this frame number is the last frame number of the previous
request. For non-repeating requests, this frame number is the
expected last frame number of the current request. The goal
is provide frame number to Java side in order to trigger
onCaptureSequenceCompleted correctly.

* Fix notifyError so that onDeviceError can be called correctly.

Bug: 10749500
Change-Id: I2f3dda6c530090055d4a2ff9f0f087bbbe8d9257
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 6a88c87..19efd30 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -221,10 +221,11 @@
 /** Device-related methods */
 
 template <typename TClientBase>
-void Camera2ClientBase<TClientBase>::notifyError(int errorCode, int arg1,
-                                                 int arg2) {
-    ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode,
-          arg1, arg2);
+void Camera2ClientBase<TClientBase>::notifyError(
+        ICameraDeviceCallbacks::CameraErrorCode errorCode,
+        const CaptureResultExtras& resultExtras) {
+    ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
+          resultExtras.requestId);
 }
 
 template <typename TClientBase>
@@ -233,13 +234,13 @@
 }
 
 template <typename TClientBase>
-void Camera2ClientBase<TClientBase>::notifyShutter(int requestId,
+void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
                                                    nsecs_t timestamp) {
-    (void)requestId;
+    (void)resultExtras;
     (void)timestamp;
 
-    ALOGV("%s: Shutter notification for request id %d at time %" PRId64,
-            __FUNCTION__, requestId, timestamp);
+    ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
+            __FUNCTION__, resultExtras.requestId, timestamp);
 }
 
 template <typename TClientBase>
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 61e44f0..9feca93 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -18,6 +18,7 @@
 #define ANDROID_SERVERS_CAMERA_CAMERA2CLIENT_BASE_H
 
 #include "common/CameraDeviceBase.h"
+#include "camera/CaptureResult.h"
 
 namespace android {
 
@@ -61,9 +62,11 @@
      * CameraDeviceBase::NotificationListener implementation
      */
 
-    virtual void          notifyError(int errorCode, int arg1, int arg2);
+    virtual void          notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+                                      const CaptureResultExtras& resultExtras);
     virtual void          notifyIdle();
-    virtual void          notifyShutter(int requestId, nsecs_t timestamp);
+    virtual void          notifyShutter(const CaptureResultExtras& resultExtras,
+                                        nsecs_t timestamp);
     virtual void          notifyAutoFocus(uint8_t newState, int triggerId);
     virtual void          notifyAutoExposure(uint8_t newState, int triggerId);
     virtual void          notifyAutoWhitebalance(uint8_t newState,
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index a4ae179..7597b10 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -24,8 +24,10 @@
 #include <utils/Timers.h>
 #include <utils/List.h>
 
+#include <camera/camera2/ICameraDeviceCallbacks.h>
 #include "hardware/camera2.h"
 #include "camera/CameraMetadata.h"
+#include "camera/CaptureResult.h"
 
 namespace android {
 
@@ -45,7 +47,7 @@
     virtual status_t initialize(camera_module_t *module) = 0;
     virtual status_t disconnect() = 0;
 
-    virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+    virtual status_t dump(int fd, const Vector<String16> &args) = 0;
 
     /**
      * The device's static characteristics metadata buffer
@@ -55,29 +57,37 @@
     /**
      * Submit request for capture. The CameraDevice takes ownership of the
      * passed-in buffer.
+     * Output lastFrameNumber is the expected frame number of this request.
      */
-    virtual status_t capture(CameraMetadata &request) = 0;
+    virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL) = 0;
 
     /**
      * Submit a list of requests.
+     * Output lastFrameNumber is the expected last frame number of the list of requests.
      */
-    virtual status_t captureList(const List<const CameraMetadata> &requests) = 0;
+    virtual status_t captureList(const List<const CameraMetadata> &requests,
+                                 int64_t *lastFrameNumber = NULL) = 0;
 
     /**
      * Submit request for streaming. The CameraDevice makes a copy of the
      * passed-in buffer and the caller retains ownership.
+     * Output lastFrameNumber is the last frame number of the previous streaming request.
      */
-    virtual status_t setStreamingRequest(const CameraMetadata &request) = 0;
+    virtual status_t setStreamingRequest(const CameraMetadata &request,
+                                         int64_t *lastFrameNumber = NULL) = 0;
 
     /**
      * Submit a list of requests for streaming.
+     * Output lastFrameNumber is the last frame number of the previous streaming request.
      */
-    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests) = 0;
+    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests,
+                                             int64_t *lastFrameNumber = NULL) = 0;
 
     /**
      * Clear the streaming request slot.
+     * Output lastFrameNumber is the last frame number of the previous streaming request.
      */
-    virtual status_t clearStreamingRequest() = 0;
+    virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL) = 0;
 
     /**
      * Wait until a request with the given ID has been dequeued by the
@@ -153,11 +163,12 @@
         // API1 and API2.
 
         // Required for API 1 and 2
-        virtual void notifyError(int errorCode, int arg1, int arg2) = 0;
+        virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+                                 const CaptureResultExtras &resultExtras) = 0;
 
         // Required only for API2
         virtual void notifyIdle() = 0;
-        virtual void notifyShutter(int requestId,
+        virtual void notifyShutter(const CaptureResultExtras &resultExtras,
                 nsecs_t timestamp) = 0;
 
         // Required only for API1
@@ -190,11 +201,12 @@
     virtual status_t waitForNextFrame(nsecs_t timeout) = 0;
 
     /**
-     * Get next metadata frame from the frame queue. Returns NULL if the queue
-     * is empty; caller takes ownership of the metadata buffer.
-     * May be called concurrently to most methods, except for waitForNextFrame
+     * Get next capture result frame from the result queue. Returns NOT_ENOUGH_DATA
+     * if the queue is empty; caller takes ownership of the metadata buffer inside
+     * the capture result object's metadata field.
+     * May be called concurrently to most methods, except for waitForNextFrame.
      */
-    virtual status_t getNextFrame(CameraMetadata *frame) = 0;
+    virtual status_t getNextResult(CaptureResult *frame) = 0;
 
     /**
      * Trigger auto-focus. The latest ID used in a trigger autofocus or cancel
@@ -235,8 +247,9 @@
     /**
      * Flush all pending and in-flight requests. Blocks until flush is
      * complete.
+     * Output lastFrameNumber is the last frame number of the previous streaming request.
      */
-    virtual status_t flush() = 0;
+    virtual status_t flush(int64_t *lastFrameNumber = NULL) = 0;
 
 };
 
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index 4d31667..f6a971a 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -99,15 +99,17 @@
 void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) {
     status_t res;
     ATRACE_CALL();
-    CameraMetadata frame;
+    CaptureResult result;
 
     ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId());
 
-    while ( (res = device->getNextFrame(&frame)) == OK) {
+    while ( (res = device->getNextResult(&result)) == OK) {
 
+        // TODO: instead of getting frame number from metadata, we should read
+        // this from result.mResultExtras when CameraDeviceBase interface is fixed.
         camera_metadata_entry_t entry;
 
-        entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
+        entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
         if (entry.count == 0) {
             ALOGE("%s: Camera %d: Error reading frame number",
                     __FUNCTION__, device->getId());
@@ -115,13 +117,13 @@
         }
         ATRACE_INT("cam2_frame", entry.data.i32[0]);
 
-        if (!processSingleFrame(frame, device)) {
+        if (!processSingleFrame(result, device)) {
             break;
         }
 
-        if (!frame.isEmpty()) {
+        if (!result.mMetadata.isEmpty()) {
             Mutex::Autolock al(mLastFrameMutex);
-            mLastFrame.acquire(frame);
+            mLastFrame.acquire(result.mMetadata);
         }
     }
     if (res != NOT_ENOUGH_DATA) {
@@ -133,21 +135,22 @@
     return;
 }
 
-bool FrameProcessorBase::processSingleFrame(CameraMetadata &frame,
-                                           const sp<CameraDeviceBase> &device) {
+bool FrameProcessorBase::processSingleFrame(CaptureResult &result,
+                                            const sp<CameraDeviceBase> &device) {
     ALOGV("%s: Camera %d: Process single frame (is empty? %d)",
-          __FUNCTION__, device->getId(), frame.isEmpty());
-    return processListeners(frame, device) == OK;
+          __FUNCTION__, device->getId(), result.mMetadata.isEmpty());
+    return processListeners(result, device) == OK;
 }
 
-status_t FrameProcessorBase::processListeners(const CameraMetadata &frame,
+status_t FrameProcessorBase::processListeners(const CaptureResult &result,
         const sp<CameraDeviceBase> &device) {
     ATRACE_CALL();
+
     camera_metadata_ro_entry_t entry;
 
     // Quirks: Don't deliver partial results to listeners that don't want them
     bool quirkIsPartial = false;
-    entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT);
+    entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT);
     if (entry.count != 0 &&
             entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
         ALOGV("%s: Camera %d: Not forwarding partial result to listeners",
@@ -155,10 +158,13 @@
         quirkIsPartial = true;
     }
 
-    entry = frame.find(ANDROID_REQUEST_ID);
+    // TODO: instead of getting requestID from CameraMetadata, we should get it
+    // from CaptureResultExtras. This will require changing Camera2Device.
+    // Currently Camera2Device uses MetadataQueue to store results, which does not
+    // include CaptureResultExtras.
+    entry = result.mMetadata.find(ANDROID_REQUEST_ID);
     if (entry.count == 0) {
-        ALOGE("%s: Camera %d: Error reading frame id",
-                __FUNCTION__, device->getId());
+        ALOGE("%s: Camera %d: Error reading frame id", __FUNCTION__, device->getId());
         return BAD_VALUE;
     }
     int32_t requestId = entry.data.i32[0];
@@ -169,9 +175,8 @@
 
         List<RangeListener>::iterator item = mRangeListeners.begin();
         while (item != mRangeListeners.end()) {
-            if (requestId >= item->minId &&
-                    requestId < item->maxId &&
-                    (!quirkIsPartial || item->quirkSendPartials) ) {
+            if (requestId >= item->minId && requestId < item->maxId &&
+                    (!quirkIsPartial || item->quirkSendPartials)) {
                 sp<FilteredListener> listener = item->listener.promote();
                 if (listener == 0) {
                     item = mRangeListeners.erase(item);
@@ -183,10 +188,12 @@
             item++;
         }
     }
-    ALOGV("Got %zu range listeners out of %zu", listeners.size(), mRangeListeners.size());
+    ALOGV("%s: Camera %d: Got %zu range listeners out of %zu", __FUNCTION__,
+          device->getId(), listeners.size(), mRangeListeners.size());
+
     List<sp<FilteredListener> >::iterator item = listeners.begin();
     for (; item != listeners.end(); item++) {
-        (*item)->onFrameAvailable(requestId, frame);
+        (*item)->onResultAvailable(result);
     }
     return OK;
 }
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.h b/services/camera/libcameraservice/common/FrameProcessorBase.h
index 89b608a..15a014e 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.h
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.h
@@ -23,6 +23,7 @@
 #include <utils/KeyedVector.h>
 #include <utils/List.h>
 #include <camera/CameraMetadata.h>
+#include <camera/CaptureResult.h>
 
 namespace android {
 
@@ -39,8 +40,7 @@
     virtual ~FrameProcessorBase();
 
     struct FilteredListener: virtual public RefBase {
-        virtual void onFrameAvailable(int32_t requestId,
-                                      const CameraMetadata &frame) = 0;
+        virtual void onResultAvailable(const CaptureResult &result) = 0;
     };
 
     // Register a listener for a range of IDs [minId, maxId). Multiple listeners
@@ -72,10 +72,10 @@
 
     void processNewFrames(const sp<CameraDeviceBase> &device);
 
-    virtual bool processSingleFrame(CameraMetadata &frame,
+    virtual bool processSingleFrame(CaptureResult &result,
                                     const sp<CameraDeviceBase> &device);
 
-    status_t processListeners(const CameraMetadata &frame,
+    status_t processListeners(const CaptureResult &result,
                               const sp<CameraDeviceBase> &device);
 
     CameraMetadata mLastFrame;