Camera NDK library: capture session implementation

Bug: 23012001
Change-Id: I3fd93205dcf1b9ed5a947cb944919eb531f219fc
diff --git a/include/camera/camera2/CaptureRequest.h b/include/camera/camera2/CaptureRequest.h
index eeab217..1dd15c4 100644
--- a/include/camera/camera2/CaptureRequest.h
+++ b/include/camera/camera2/CaptureRequest.h
@@ -25,7 +25,7 @@
 
 class Surface;
 
-struct CaptureRequest : public virtual RefBase {
+struct CaptureRequest : public RefBase {
 public:
 
     CameraMetadata          mMetadata;
diff --git a/include/camera/camera2/OutputConfiguration.h b/include/camera/camera2/OutputConfiguration.h
index d6b74a9..137d98c 100644
--- a/include/camera/camera2/OutputConfiguration.h
+++ b/include/camera/camera2/OutputConfiguration.h
@@ -17,14 +17,13 @@
 #ifndef ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H
 #define ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H
 
-#include <utils/RefBase.h>
 #include <gui/IGraphicBufferProducer.h>
 
 namespace android {
 
 class Surface;
 
-class OutputConfiguration : public virtual RefBase {
+class OutputConfiguration {
 public:
 
     static const int INVALID_ROTATION;
@@ -44,6 +43,22 @@
     OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
             int surfaceSetID = INVALID_SET_ID);
 
+    bool operator == (const OutputConfiguration& other) const {
+        return (mGbp == other.mGbp &&
+                mRotation == other.mRotation);
+    }
+    bool operator != (const OutputConfiguration& other) const {
+        return !(*this == other);
+    }
+    bool operator < (const OutputConfiguration& other) const {
+        if (*this == other) return false;
+        if (mGbp != other.mGbp) return mGbp < other.mGbp;
+        return mRotation < other.mRotation;
+    }
+    bool operator > (const OutputConfiguration& other) const {
+        return (*this != other && !(*this < other));
+    }
+
 private:
     sp<IGraphicBufferProducer> mGbp;
     int                        mRotation;
diff --git a/include/camera/ndk/NdkCameraCaptureSession.h b/include/camera/ndk/NdkCameraCaptureSession.h
index b3367c7..5d5cae2 100644
--- a/include/camera/ndk/NdkCameraCaptureSession.h
+++ b/include/camera/ndk/NdkCameraCaptureSession.h
@@ -39,27 +39,32 @@
 
 typedef struct ACameraCaptureSession_stateCallbacks {
     void*                               context;
-    ACameraCaptureSession_stateCallback onConfigured;
-    ACameraCaptureSession_stateCallback onConfigureFailed;
-    ACameraCaptureSession_stateCallback onClosed;
+    ACameraCaptureSession_stateCallback onClosed; // session is unusable after this callback
     ACameraCaptureSession_stateCallback onReady;
     ACameraCaptureSession_stateCallback onActive;
 } ACameraCaptureSession_stateCallbacks;
 
+enum {
+    CAPTURE_FAILURE_REASON_FLUSHED = 0,
+    CAPTURE_FAILURE_REASON_ERROR
+};
+
 typedef struct ACameraCaptureFailure {
-    uint32_t frameNumber;
-    int      reason;
-    int      sequenceId;
-    int      wasImageCaptured;
+    int64_t frameNumber;
+    int     reason;
+    int     sequenceId;
+    bool    wasImageCaptured;
 } ACameraCaptureFailure;
 
+/* Note that the ACaptureRequest* in the callback will be different to what app has submitted,
+   but the contents will still be the same as what app submitted */
 typedef void (*ACameraCaptureSession_captureCallback_start)(
         void* context, ACameraCaptureSession* session,
-        ACaptureRequest* request, long timestamp);
+        const ACaptureRequest* request, int64_t timestamp);
 
 typedef void (*ACameraCaptureSession_captureCallback_result)(
         void* context, ACameraCaptureSession* session,
-        ACaptureRequest* request, ACameraMetadata* result);
+        ACaptureRequest* request, const ACameraMetadata* result);
 
 typedef void (*ACameraCaptureSession_captureCallback_failed)(
         void* context, ACameraCaptureSession* session,
@@ -67,22 +72,30 @@
 
 typedef void (*ACameraCaptureSession_captureCallback_sequenceEnd)(
         void* context, ACameraCaptureSession* session,
-        int sequenceId, long frameNumber);
+        int sequenceId, int64_t frameNumber);
+
+typedef void (*ACameraCaptureSession_captureCallback_sequenceAbort)(
+        void* context, ACameraCaptureSession* session,
+        int sequenceId);
 
 typedef struct ACameraCaptureSession_captureCallbacks {
     void*                                             context;
-    ACameraCaptureSession_captureCallback_start       onCaptureStarted;
-    ACameraCaptureSession_captureCallback_result      onCaptureProgressed;
-    ACameraCaptureSession_captureCallback_result      onCaptureCompleted;
-    ACameraCaptureSession_captureCallback_failed      onCaptureFailed;
-    ACameraCaptureSession_captureCallback_sequenceEnd onCaptureSequenceCompleted;
-    ACameraCaptureSession_captureCallback_sequenceEnd onCaptureSequenceAborted;
+    ACameraCaptureSession_captureCallback_start         onCaptureStarted;
+    ACameraCaptureSession_captureCallback_result        onCaptureProgressed;
+    ACameraCaptureSession_captureCallback_result        onCaptureCompleted;
+    ACameraCaptureSession_captureCallback_failed        onCaptureFailed;
+    ACameraCaptureSession_captureCallback_sequenceEnd   onCaptureSequenceCompleted;
+    ACameraCaptureSession_captureCallback_sequenceAbort onCaptureSequenceAborted;
 } ACameraCaptureSession_captureCallbacks;
 
+enum {
+    CAPTURE_SEQUENCE_ID_NONE = -1
+};
+
 /*
  * Close capture session
  */
-camera_status_t ACameraCaptureSession_close(ACameraCaptureSession*);
+void ACameraCaptureSession_close(ACameraCaptureSession*);
 
 struct ACameraDevice;
 typedef struct ACameraDevice ACameraDevice;
@@ -98,14 +111,16 @@
  */
 camera_status_t ACameraCaptureSession_capture(
         ACameraCaptureSession*, /*optional*/ACameraCaptureSession_captureCallbacks*,
-        int numRequests, const ACaptureRequest* requests);
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId);
 
 /**
  * Send repeating capture request(s)
  */
 camera_status_t ACameraCaptureSession_setRepeatingRequest(
         ACameraCaptureSession*, /*optional*/ACameraCaptureSession_captureCallbacks*,
-        int numRequests, const ACaptureRequest* requests);
+        int numRequests, ACaptureRequest** requests,
+        /*optional*/int* captureSequenceId);
 
 /**
  * Stop repeating capture request(s)
diff --git a/include/camera/ndk/NdkCameraDevice.h b/include/camera/ndk/NdkCameraDevice.h
index 6eb0707..2008a68 100644
--- a/include/camera/ndk/NdkCameraDevice.h
+++ b/include/camera/ndk/NdkCameraDevice.h
@@ -44,8 +44,8 @@
 
 typedef struct ACameraDevice_StateCallbacks {
     void*                             context;
-    ACameraDevice_StateCallback       onDisconnected;
-    ACameraDevice_ErrorStateCallback  onError;
+    ACameraDevice_StateCallback       onDisconnected; // Device is unusable after this callback
+    ACameraDevice_ErrorStateCallback  onError;        // Device is unusable after this callback
 } ACameraDevice_stateCallbacks;
 
 /**
@@ -93,10 +93,17 @@
 camera_status_t ACaptureSessionOutputContainer_remove(
         ACaptureSessionOutputContainer*, const ACaptureSessionOutput*);
 
+/*
+ * Create a new capture session.
+ * If there is a preexisting session, the previous session will be closed automatically.
+ * However, app still needs to call ACameraCaptureSession_close on previous session.
+ * Otherwise the resources hold by previous session won't be freed
+ */
 camera_status_t ACameraDevice_createCaptureSession(
         ACameraDevice*,
         const ACaptureSessionOutputContainer*       outputs,
-        const ACameraCaptureSession_stateCallbacks* callbacks);
+        const ACameraCaptureSession_stateCallbacks* callbacks,
+        /*out*/ACameraCaptureSession** session);
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/include/camera/ndk/NdkCameraError.h b/include/camera/ndk/NdkCameraError.h
index 94a6942..6d671de 100644
--- a/include/camera/ndk/NdkCameraError.h
+++ b/include/camera/ndk/NdkCameraError.h
@@ -47,7 +47,11 @@
     ACAMERA_ERROR_CAMERA_REQUEST        = ACAMERA_ERROR_BASE - 8,
     ACAMERA_ERROR_CAMERA_RESULT         = ACAMERA_ERROR_BASE - 9,
     ACAMERA_ERROR_CAMERA_BUFFER         = ACAMERA_ERROR_BASE - 10,
-
+    ACAMERA_ERROR_SESSION_CLOSED        = ACAMERA_ERROR_BASE - 11,
+    ACAMERA_ERROR_SESSION_NOT_DRAINED   = ACAMERA_ERROR_BASE - 12,
+    ACAMERA_ERROR_INVALID_OPERATION     = ACAMERA_ERROR_BASE - 13,
+    ACAMERA_ERROR_TIMEOUT               = ACAMERA_ERROR_BASE - 14,
+    ACAMERA_ERROR_STREAM_CONFIGURE_FAIL = ACAMERA_ERROR_BASE - 15,
 } camera_status_t;
 
 
diff --git a/include/camera/ndk/NdkCaptureRequest.h b/include/camera/ndk/NdkCaptureRequest.h
index 44b36d9..566d78f 100644
--- a/include/camera/ndk/NdkCaptureRequest.h
+++ b/include/camera/ndk/NdkCaptureRequest.h
@@ -42,11 +42,12 @@
 
 typedef struct ACaptureRequest ACaptureRequest;
 
-camera_status_t ACameraOutputTarget_create(ANativeWindow*);
+camera_status_t ACameraOutputTarget_create(ANativeWindow* window, ACameraOutputTarget** out);
 void ACameraOutputTarget_free(ACameraOutputTarget*);
 
 camera_status_t ACaptureRequest_addTarget(ACaptureRequest*, const ACameraOutputTarget*);
 camera_status_t ACaptureRequest_removeTarget(ACaptureRequest*, const ACameraOutputTarget*);
+//TODO: do we need API to query added targets?
 
 /*
  * Get a metadata entry