modules: camera: default request templates

Change-Id: I0a4b389e1850c10e12a65b3c8a5670c78c6746f7
diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp
index 3bafdf4..0a0b493 100644
--- a/modules/camera/Camera.cpp
+++ b/modules/camera/Camera.cpp
@@ -135,6 +135,29 @@
 {
     ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
     mCallbackOps = callback_ops;
+    // Create standard settings templates
+    // 0 is invalid as template
+    mTemplates[0] = NULL;
+    // CAMERA3_TEMPLATE_PREVIEW = 1
+    mTemplates[1] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
+    // CAMERA3_TEMPLATE_STILL_CAPTURE = 2
+    mTemplates[2] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+    // CAMERA3_TEMPLATE_VIDEO_RECORD = 3
+    mTemplates[3] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+    // CAMERA3_TEMPLATE_VIDEO_SNAPSHOT = 4
+    mTemplates[4] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+    // CAMERA3_TEMPLATE_STILL_ZERO_SHUTTER_LAG = 5
+    mTemplates[5] = new Metadata(ANDROID_CONTROL_MODE_OFF,
+            ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG);
+    // Pre-generate metadata structures
+    for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
+        mTemplates[i]->generate();
+    }
+    // TODO: create vendor templates
     return 0;
 }
 
@@ -445,8 +468,12 @@
 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
 {
     ALOGV("%s:%d: type=%d", __func__, mId, type);
-    // TODO: return statically built default request
-    return NULL;
+
+    if (type < 1 || type >= CAMERA3_TEMPLATE_COUNT) {
+        ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
+        return NULL;
+    }
+    return mTemplates[type]->generate();
 }
 
 int Camera::processCaptureRequest(camera3_capture_request_t *request)
diff --git a/modules/camera/Camera.h b/modules/camera/Camera.h
index e97dfd0..c7ee52d 100644
--- a/modules/camera/Camera.h
+++ b/modules/camera/Camera.h
@@ -91,6 +91,8 @@
         Stream **mStreams;
         // Number of streams in mStreams
         int mNumStreams;
+        // Static array of standard camera settings templates
+        Metadata *mTemplates[CAMERA3_TEMPLATE_COUNT];
         // Most recent request settings seen, memoized to be reused
         camera_metadata_t *mSettings;
 };
diff --git a/modules/camera/Metadata.cpp b/modules/camera/Metadata.cpp
index 77f5405..ad97b26 100644
--- a/modules/camera/Metadata.cpp
+++ b/modules/camera/Metadata.cpp
@@ -43,6 +43,33 @@
 {
 }
 
+Metadata::Metadata(uint8_t mode, uint8_t intent)
+  : mHead(NULL),
+    mTail(NULL),
+    mEntryCount(0),
+    mDataCount(0)
+{
+    pthread_mutex_init(&mMutex, NULL);
+
+    if (validate(ANDROID_CONTROL_MODE, TYPE_BYTE, 1)) {
+        int res = add(ANDROID_CONTROL_MODE, 1, &mode);
+        if (res != 0) {
+            ALOGE("%s: Unable to add mode to template!", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid mode constructing template!", __func__);
+    }
+
+    if (validate(ANDROID_CONTROL_CAPTURE_INTENT, TYPE_BYTE, 1)) {
+        int res = add(ANDROID_CONTROL_CAPTURE_INTENT, 1, &intent);
+        if (res != 0) {
+            ALOGE("%s: Unable to add capture intent to template!", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid capture intent constructing template!", __func__);
+    }
+}
+
 int Metadata::addUInt8(uint32_t tag, int count, uint8_t *data)
 {
     if (!validate(tag, TYPE_BYTE, count)) return -EINVAL;
@@ -113,9 +140,11 @@
         return -ENOMEM;
     memcpy(data, tag_data, count * type_sz);
 
+    pthread_mutex_lock(&mMutex);
     mEntryCount++;
     mDataCount += calculate_camera_metadata_entry_data_size(tag_type, count);
     push(new Entry(tag, data, count));
+    pthread_mutex_unlock(&mMutex);
     return 0;
 }
 
diff --git a/modules/camera/Metadata.h b/modules/camera/Metadata.h
index d5aac36..283e4a7 100644
--- a/modules/camera/Metadata.h
+++ b/modules/camera/Metadata.h
@@ -28,6 +28,8 @@
     public:
         Metadata();
         ~Metadata();
+        // Constructor used for request metadata templates
+        Metadata(uint8_t mode, uint8_t intent);
 
         // Parse and add an entry
         int addUInt8(uint32_t tag, int count, uint8_t *data);