Camera: codegen NDK metadata tag header

Bug: 23012001
Change-Id: I049eb42fcf2103854179d841a3dfb51f728905bc
diff --git a/camera/docs/ACameraMetadata.mako b/camera/docs/ACameraMetadata.mako
new file mode 100644
index 0000000..49238b0
--- /dev/null
+++ b/camera/docs/ACameraMetadata.mako
@@ -0,0 +1,67 @@
+## -*- coding: utf-8 -*-
+##
+## Copyright (C) 2015 The Android Open Source Project
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+\
+## Generate a list of only Static, Controls, or Dynamic properties.
+<%def name="single_kind_keys(kind_name)">\
+% for outer_namespace in metadata.outer_namespaces: ## assumes single 'android' namespace
+  % for section in outer_namespace.sections:
+    % if section.find_first(lambda x: isinstance(x, metadata_model.Entry) and x.kind == kind_name) and \
+         any_visible(section, kind_name, ('public','hidden') ):
+      % for inner_namespace in get_children_by_filtering_kind(section, kind_name, 'namespaces'):
+## We only support 1 level of inner namespace, i.e. android.a.b and android.a.b.c works, but not android.a.b.c.d
+## If we need to support more, we should use a recursive function here instead.. but the indentation gets trickier.
+        % for entry in filter_visibility(inner_namespace.merged_entries, ('hidden','public')):
+          % if not entry.synthetic:
+        case ${ndk(entry.name) | csym}:
+          % endif
+       % endfor
+    % endfor
+    % for entry in filter_visibility( \
+        get_children_by_filtering_kind(section, kind_name, 'merged_entries'), \
+                                         ('hidden', 'public')):
+      % if not entry.synthetic:
+        case ${ndk(entry.name) | csym}:
+      % endif
+    % endfor
+    % endif
+  % endfor
+% endfor
+</%def>\
+/*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+ * The key entries below this point are generated from metadata
+ * definitions in /system/media/camera/docs. Do not modify by hand or
+ * modify the comment blocks at the start or end.
+ *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+bool
+ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
+    // Skip check for vendor keys
+    if (isVendorTag(tag)) {
+        return true;
+    }
+
+    switch (tag) {
+${single_kind_keys("controls")}\
+            return true;
+        default:
+            return false;
+    }
+}
+
+/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+ * End generated code
+ *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/camera/docs/metadata-generate b/camera/docs/metadata-generate
index 4d74212..6009c40 100755
--- a/camera/docs/metadata-generate
+++ b/camera/docs/metadata-generate
@@ -21,6 +21,8 @@
 #   docs.html
 #   ../src/camera_metadata_tag_info.c
 #   ../src/camera_metadata_tags.h
+#   ../../../../frameworks/av/include/camera/ndk/NdkCameraMetadataTags.h
+#   ../../../../frameworks/av/camera/ndk/impl/ACameraMetadata.cpp
 #   ../../../../cts/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
 #   ../../../../frameworks/base/core/java/android/hardware/camera2/CameraCharacteristics.java
 #   ../../../../frameworks/base/core/java/android/hardware/camera2/CaptureRequest.java
@@ -36,6 +38,8 @@
 fwkdir_html="$ANDROID_BUILD_TOP/frameworks/base/docs/html"
 ctsdir="$ANDROID_BUILD_TOP/cts/tests/camera/src/android/hardware/camera2/cts"
 outdir="$ANDROID_PRODUCT_OUT/obj/ETC/system-media-camera-docs_intermediates"
+ndk_header_dir="$ANDROID_BUILD_TOP/frameworks/av/include/camera/ndk"
+ndk_impl_dir="$ANDROID_BUILD_TOP/frameworks/av/camera/ndk/impl"
 out_files=()
 
 function relpath() {
@@ -190,6 +194,9 @@
 gen_file camera_metadata_tag_info.mako ../src/camera_metadata_tag_info.c || exit 1
 gen_file camera_metadata_tags.mako ../include/system/camera_metadata_tags.h || exit 1
 
+#Generate NDK header
+gen_file_abs ndk_camera_metadata_tags.mako "$ndk_header_dir/NdkCameraMetadataTags.h" || exit 1
+
 # Generate Java API definitions
 mkdir -p "${outdir}"
 gen_file_abs CameraMetadataEnums.mako "$outdir/CameraMetadataEnums.java.part" no || exit 1
@@ -204,6 +211,10 @@
 insert_file "$outdir/CaptureResultKeys.java.part" "$fwkdir/CaptureResult.java" || exit 1
 insert_file "$outdir/CaptureResultTest.java.part" "$ctsdir/CaptureResultTest.java" || exit 1
 
+# Generate NDK implementation
+gen_file_abs ACameraMetadata.mako "$outdir/ACameraMetadata.cpp.part" no || exit 1
+insert_file "$outdir/ACameraMetadata.cpp.part" "$ndk_impl_dir/ACameraMetadata.cpp" || exit 1
+
 # Copy ./images directory into javadoc directory
 copy_directory "images" "$fwkdir_html" || exit 1
 
diff --git a/camera/docs/metadata_helpers.py b/camera/docs/metadata_helpers.py
index 9a6fe9b..fe1927d 100644
--- a/camera/docs/metadata_helpers.py
+++ b/camera/docs/metadata_helpers.py
@@ -127,6 +127,22 @@
 
   return ".".join((i.name for i in path))
 
+def ndk(name):
+  """
+  Return the NDK version of given name, which replace
+  the leading "android" to "acamera"
+
+  Args:
+    name: name string of an entry
+
+  Returns:
+    A NDK version name string of the input name
+  """
+  name_list = name.split(".")
+  if name_list[0] == "android":
+    name_list[0] = "acamera"
+  return ".".join(name_list)
+
 def has_descendants_with_enums(node):
   """
   Determine whether or not the current node is or has any descendants with an
diff --git a/camera/docs/ndk_camera_metadata_tags.mako b/camera/docs/ndk_camera_metadata_tags.mako
new file mode 100644
index 0000000..ba6164f
--- /dev/null
+++ b/camera/docs/ndk_camera_metadata_tags.mako
@@ -0,0 +1,118 @@
+## -*- coding: utf-8 -*-
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file defines an NDK API.
+ * Do not remove methods.
+ * Do not change method signatures.
+ * Do not change the value of constants.
+ * Do not change the size of any of the classes defined in here.
+ * Do not reference types that are not part of the NDK.
+ * Do not #include files that aren't part of the NDK.
+ */
+
+#ifndef _NDK_CAMERA_METADATA_TAGS_H
+#define _NDK_CAMERA_METADATA_TAGS_H
+<%!
+  def annotated_type(entry):
+    type = entry.type
+    if entry.container == 'array':
+       type += '[' + '*'.join(entry.container_sizes) + ']'
+    if entry.enum:
+       type += ' (enum)'
+
+    return type
+%>\
+\
+
+typedef enum acamera_metadata_section {
+  % for i in find_all_sections(metadata):
+    ${ndk(path_name(i)) | csym},
+  % endfor
+    ACAMERA_SECTION_COUNT,
+
+    ACAMERA_VENDOR = 0x8000
+} acamera_metadata_section_t;
+
+/**
+ * Hierarchy positions in enum space.
+ */
+typedef enum acamera_metadata_section_start {
+  % for i in find_all_sections(metadata):
+    ${ndk(path_name(i)) + '.start' | csym,ljust(30)} = ${ndk(path_name(i)) | csym,pad(64)} << 16,
+  % endfor
+    ACAMERA_VENDOR_START           = ACAMERA_VENDOR            << 16
+} acamera_metadata_section_start_t;
+
+/**
+ * Main enum for camera metadata tags.
+ */
+typedef enum acamera_metadata_tag {
+    % for sec in find_all_sections(metadata):
+      % for idx,entry in enumerate(remove_synthetic(find_unique_entries(sec))):
+        % if idx == 0:
+          % if entry.applied_visibility != "system":
+            % if entry.deprecated:
+    ${ndk(entry.name) + " = " | csym,ljust(60)}// Deprecated! DO NOT USE
+            % else:
+    ${ndk(entry.name) + " = " | csym,ljust(60)}// ${annotated_type(entry)}
+            % endif
+          % else:
+    ${ndk(path_name(find_parent_section(entry))) | csym}_RESERVED_${idx} =
+          % endif
+            ${ndk(path_name(find_parent_section(entry))) | csym}_START,
+        % else:
+          % if entry.applied_visibility != "system":
+            % if entry.deprecated:
+    ${ndk(entry.name) + "," | csym,ljust(60)}// Deprecated! DO NOT USE
+            % else:
+    ${ndk(entry.name) + "," | csym,ljust(60)}// ${annotated_type(entry)}
+            % endif
+          % else:
+    ${ndk(path_name(find_parent_section(entry))) | csym}_RESERVED_${idx},
+          % endif
+        % endif
+      % endfor
+    ${ndk(path_name(sec)) | csym}_END,
+
+    %endfor
+} acamera_metadata_tag_t;
+
+/**
+ * Enumeration definitions for the various entries that need them
+ */
+
+% for sec in find_all_sections(metadata):
+  % for entry in filter_visibility(remove_synthetic(find_unique_entries(sec)), ("public", "hidden")):
+    % if entry.enum:
+// ${ndk(entry.name) | csym}
+typedef enum acamera_metadata_enum_${csym(ndk(entry.name)).lower()} {
+      % for val in entry.enum.values:
+        % if val.id is None:
+    ${ndk(entry.name) | csym}_${val.name},
+        % else:
+    ${'%s_%s'%(csym(ndk(entry.name)), val.name) | pad(65)} = ${val.id},
+        % endif
+      % endfor
+} acamera_metadata_enum_${csym(entry.name).lower()}_t;
+
+    % endif
+  % endfor
+
+%endfor
+
+#endif //_NDK_CAMERA_METADATA_TAGS_H