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);
diff --git a/modules/camera/Camera.h b/modules/camera/Camera.h
index c43e207..1d88cf3 100644
--- a/modules/camera/Camera.h
+++ b/modules/camera/Camera.h
@@ -59,6 +59,8 @@
         bool isValidStreamSet(Stream **array, int count);
         // Calculate usage and max_bufs of each stream
         void setupStreams(Stream **array, int count);
+        // Copy new settings for re-use and clean up old settings.
+        void setSettings(const camera_metadata_t *new_settings);
 
         // Identifier used by framework to distinguish cameras
         const int mId;
@@ -74,6 +76,8 @@
         Stream **mStreams;
         // Number of streams in mStreams
         int mNumStreams;
+        // Most recent request settings seen, memoized to be reused
+        camera_metadata_t *mSettings;
 };
 } // namespace default_camera_hal