modules: camera: memoize request settings metadata

Change-Id: I19c3a6a55a42e60f627702cd4a995664a0dfc4d2
diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp
index 21ac232..7f53c2e 100644
--- a/modules/camera/Camera.cpp
+++ b/modules/camera/Camera.cpp
@@ -17,6 +17,7 @@
 #include <cstdlib>
 #include <pthread.h>
 #include <hardware/camera3.h>
+#include <system/camera_metadata.h>
 #include "CameraHAL.h"
 #include "Stream.h"
 
@@ -47,7 +48,8 @@
     mBusy(false),
     mCallbackOps(NULL),
     mStreams(NULL),
-    mNumStreams(0)
+    mNumStreams(0),
+    mSettings(NULL)
 {
     pthread_mutex_init(&mMutex,
                        NULL); // No pthread mutex attributes.
@@ -164,6 +166,9 @@
     mStreams = newStreams;
     mNumStreams = stream_config->num_streams;
 
+    // Clear out last seen settings metadata
+    setSettings(NULL);
+
     pthread_mutex_unlock(&mMutex);
     return 0;
 
@@ -291,10 +296,35 @@
         return -EINVAL;
     }
 
+    ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
+            request->frame_number, request->settings);
+
+    // NULL indicates use last settings
+    if (request->settings == NULL) {
+        if (mSettings == NULL) {
+            ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
+                    __func__, mId, request->frame_number, request);
+            return -EINVAL;
+        }
+    } else {
+        setSettings(request->settings);
+    }
+
     // TODO: verify request; submit request to hardware
     return 0;
 }
 
+void Camera::setSettings(const camera_metadata_t *new_settings)
+{
+    if (mSettings != NULL) {
+        free_camera_metadata(mSettings);
+        mSettings = NULL;
+    }
+
+    if (new_settings != NULL)
+        mSettings = clone_camera_metadata(new_settings);
+}
+
 void Camera::getMetadataVendorTagOps(vendor_tag_query_ops_t *ops)
 {
     ALOGV("%s:%d: ops=%p", __func__, mId, ops);