Camera: Generate camera_metadata_tags.h from XML

Change-Id: Ie98f9dca854841ff1430c1314fbc570e26e5398b
diff --git a/camera/docs/camera_metadata_tags.mako b/camera/docs/camera_metadata_tags.mako
new file mode 100644
index 0000000..184bc01
--- /dev/null
+++ b/camera/docs/camera_metadata_tags.mako
@@ -0,0 +1,168 @@
+## -*- coding: utf-8 -*-
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/**
+ * !! Do not include this file directly !!
+ *
+ * Include camera_metadata.h instead.
+ */
+
+/**
+ * ! Do not edit this file directly !
+ *
+ * Generated automatically from camera_metadata_tags.mako
+ */
+
+<%!
+  import metadata_model
+
+  def _is_sec_or_ins(x):
+    return isinstance(x, metadata_model.Section) or    \
+           isinstance(x, metadata_model.InnerNamespace)
+
+  ##
+  ## Metadata Helpers
+  ##
+
+  def find_all_sections(root):
+    return root.find_all(_is_sec_or_ins)
+
+  def find_parent_section(entry):
+    return entry.find_parent_first(_is_sec_or_ins)
+
+  # find uniquely named entries (w/o recursing through inner namespaces)
+  def find_unique_entries(node):
+    if not isinstance(node, metadata_model.Section) and    \
+       not isinstance(node, metadata_model.InnerNamespace):
+      raise TypeError("expected node to be a Section or InnerNamespace")
+
+    d = {}
+    # remove the 'kinds' from the path between sec and the closest entries
+    # then search the immediate children of the search path
+    search_path = isinstance(node, metadata_model.Section) and node.kinds \
+                  or [node]
+    for i in search_path:
+        for entry in i.entries:
+            d[entry.name] = entry
+
+    for k,v in d.iteritems():
+        yield v
+
+  def path_name(node):
+    isa = lambda x,y: isinstance(x, y)
+    fltr = lambda x: not isa(x, metadata_model.Metadata) and \
+                     not isa(x, metadata_model.Kind)
+
+    path = node.find_parents(fltr)
+    path = list(path)
+    path.reverse()
+    path.append(node)
+
+    return ".".join((i.name for i in path))
+
+  ##
+  ## Filters
+  ##
+
+  # abcDef.xyz -> ABC_DEF_XYZ
+  def csym(name):
+    newstr = name
+    newstr = "".join([i.isupper() and ("_" + i) or i for i in newstr]).upper()
+    newstr = newstr.replace(".", "_")
+    return newstr
+
+  # pad with spaces to make string len == size. add new line if too big
+  def ljust(size, indent=4):
+    def inner(what):
+        newstr = what.ljust(size)
+        if len(newstr) > size:
+            return what + "\n" + "".ljust(indent + size)
+        else:
+            return newstr
+    return inner
+%>
+
+/** TODO: Nearly every enum in this file needs a description */
+
+/**
+ * Top level hierarchy definitions for camera metadata. *_INFO sections are for
+ * the static metadata that can be retrived without opening the camera device.
+ * New sections must be added right before ANDROID_SECTION_COUNT to maintain
+ * existing enumerations.
+ */
+typedef enum camera_metadata_section {
+  % for i in find_all_sections(metadata):
+    ${path_name(i) | csym},
+  % endfor
+    ANDROID_SECTION_COUNT,
+
+    VENDOR_SECTION = 0x8000
+} camera_metadata_section_t;
+
+/**
+ * Hierarchy positions in enum space. All vendor extension tags must be
+ * defined with tag >= VENDOR_SECTION_START
+ */
+typedef enum camera_metadata_section_start {
+  % for i in find_all_sections(metadata):
+    ${path_name(i) + '.start' | csym,ljust(30)} = ${path_name(i) | csym,ljust(25)} << 16,
+  % endfor
+    VENDOR_SECTION_START           = VENDOR_SECTION            << 16
+} camera_metadata_section_start_t;
+
+/**
+ * Main enum for defining camera metadata tags.  New entries must always go
+ * before the section _END tag to preserve existing enumeration values.  In
+ * addition, the name and type of the tag needs to be added to
+ * system/media/camera/src/camera_metadata_tag_info.c
+ */
+enum camera_metadata_tag {
+    % for sec in find_all_sections(metadata):
+      % for idx,entry in enumerate(find_unique_entries(sec)):
+        % if idx == 0:
+    ${entry.name | csym,ljust(30)} = ${path_name(find_parent_section(entry)) | csym}_START,
+        % else:
+    ${entry.name | csym},
+        % endif
+      % endfor
+    ${path_name(sec) | csym}_END,
+
+    %endfor
+} camera_metadata_tag_t;
+
+/**
+ * Enumeration definitions for the various entries that need them
+ */
+
+% for sec in find_all_sections(metadata):
+  % for entry in find_unique_entries(sec):
+    % if entry.type == 'enum':
+// ${entry.name | csym}
+typedef enum camera_metadata_enum_${csym(entry.name).lower()} {
+      % for val in entry.enum.values:
+        % if val.id is None:
+    ${entry.name | csym}_${val.name},
+        % else:
+    ${'%s_%s'%(csym(entry.name), val.name) | ljust(30)} = ${val.id},
+        % endif
+      % endfor
+} camera_metadata_enum_${csym(entry.name).lower()}_t;
+
+    % endif
+  % endfor
+
+%endfor
diff --git a/camera/docs/metadata-parser-sanity-check b/camera/docs/metadata-parser-sanity-check
index e47ec0b..940300c 100755
--- a/camera/docs/metadata-parser-sanity-check
+++ b/camera/docs/metadata-parser-sanity-check
@@ -34,7 +34,7 @@
 tmp_tidy1=$(mktemp)
 tmp_tidy2=$(mktemp)
 
-$thisdir/metadata_parser_xml.py $thisdir/metadata_properties.xml $thisdir/metadata_template.mako > $tmp_out
+$thisdir/metadata_parser_xml.py $thisdir/metadata_properties.xml $thisdir/metadata_template.mako > $tmp_out || exit 1
 tidy -indent -xml -quiet $thisdir/metadata_properties.xml > $tmp_tidy1
 tidy -indent -xml -quiet $tmp_out > $tmp_tidy2
 
diff --git a/camera/docs/metadata_model.py b/camera/docs/metadata_model.py
index e916c69..1acf2b5 100644
--- a/camera/docs/metadata_model.py
+++ b/camera/docs/metadata_model.py
@@ -1024,6 +1024,17 @@
     """
     return self.get_name_as_list()[-1]
 
+  def get_path_without_name(self):
+    """
+    Returns a string path to the entry, with the name component excluded.
+
+    For example:
+      entry.name is 'android.lens.info.shading'
+      entry.get_path_without_name() == 'android.lens.info'
+    """
+    return ".".join(self.get_name_as_list()[0:-1])
+
+
 class Clone(Entry):
   """
   A Node corresponding to a <clone> element. It has all the attributes of an
diff --git a/camera/docs/metadata_properties.xml b/camera/docs/metadata_properties.xml
index b52919e..127a740 100644
--- a/camera/docs/metadata_properties.xml
+++ b/camera/docs/metadata_properties.xml
@@ -867,23 +867,6 @@
         </entry>
       </controls>
     </section>
-    <section name="hotPIxel">
-      <static>
-        <namespace name="info">
-          <entry name="map" type="int32"
-          type_notes="list of coordinates based on android.sensor.pixelArraySize"
-          container="array">
-            <array>
-              <size>2</size>
-              <size>n</size>
-            </array>
-            <description>Location of hot/defective pixels on
-            sensor</description>
-            <tag id="ADV" />
-          </entry>
-        </namespace>
-      </static>
-    </section>
     <section name="hotPixel">
       <controls>
         <entry name="mode" type="enum">
@@ -903,6 +886,21 @@
           <tag id="V1" />
         </entry>
       </controls>
+      <static>
+        <namespace name="info">
+          <entry name="map" type="int32"
+          type_notes="list of coordinates based on android.sensor.pixelArraySize"
+          container="array">
+            <array>
+              <size>2</size>
+              <size>n</size>
+            </array>
+            <description>Location of hot/defective pixels on
+            sensor</description>
+            <tag id="ADV" />
+          </entry>
+        </namespace>
+      </static>
       <dynamic>
         <clone entry="android.hotPixel.mode" kind="controls">
           <tag id="V1" />
diff --git a/camera/docs/metadata_template.mako b/camera/docs/metadata_template.mako
index 1afc67e..84ac43d 100644
--- a/camera/docs/metadata_template.mako
+++ b/camera/docs/metadata_template.mako
@@ -22,7 +22,7 @@
 <tags>
 % for tag in metadata.tags:
   % if tag.description and tag.description.strip():
-  <tag id="${tag.id}">${tag.description}</tag>
+  <tag id="${tag.id}">${tag.description | x}</tag>
   % else:
   <tag id="${tag.id}"><!-- TODO: fill the tag description --></tag>
   % endif