camera_metadata: add typedefs for java generated code
Change-Id: I619261b9645cda669a3b5ee7c79f4c56d4d4c3d4
diff --git a/camera/docs/CameraMetadataKeys.mako b/camera/docs/CameraMetadataKeys.mako
index 1c8d47c..2879d83 100644
--- a/camera/docs/CameraMetadataKeys.mako
+++ b/camera/docs/CameraMetadataKeys.mako
@@ -47,7 +47,7 @@
* @hide
*/
%endif
- public static final class ${entry.get_name_minimal() | pascal_case}Key extends Key<${jtype(entry)}> {
+ public static final class ${entry.get_name_minimal() | pascal_case}Key extends Key<${jtype_boxed(entry)}> {
public enum Enum {
% for value,last in enumerate_with_last(entry.enum.values):
${value.name | jidentifier}${"," if not last else ";"}
@@ -60,7 +60,7 @@
// TODO: remove requirement for constructor by making Key an interface
private ${entry.get_name_minimal() | pascal_case}Key(String name) {
- super(name, ${jtype(entry)}.class);
+ super(name, ${jtype_boxed(entry)}.class);
}
% if entry.enum.has_values_with_id:
@@ -93,14 +93,14 @@
## If we need to support more, we should use a recursive function here instead.. but the indentation gets trickier.
public static final class ${inner_namespace.name| pascal_case} {
% for entry in filter_visibility(inner_namespace.merged_entries, ('hidden','public')):
- % if entry.enum:
+ % if entry.enum and not (entry.typedef and not entry.typedef.languages.get('java')):
${generate_enum(entry)}
% if entry.applied_visibility == 'hidden':
/**
* @hide
*/
%endif
- public static final Key<${jtype(entry)}> ${entry.get_name_minimal() | csym} =
+ public static final Key<${jtype_boxed(entry)}> ${entry.get_name_minimal() | csym} =
new ${entry.get_name_minimal() | pascal_case}Key("${entry.name}");
% else:
% if entry.applied_visibility == 'hidden':
@@ -108,8 +108,8 @@
* @hide
*/
%endif
- public static final Key<${jtype(entry)}> ${entry.get_name_minimal() | csym} =
- new Key<${jtype(entry)}>("${entry.name}", ${jclass(entry)});
+ public static final Key<${jtype_boxed(entry)}> ${entry.get_name_minimal() | csym} =
+ new Key<${jtype_boxed(entry)}>("${entry.name}", ${jclass(entry)});
% endif
% endfor
}
@@ -117,14 +117,14 @@
% for entry in filter_visibility( \
get_children_by_filtering_kind(section, xml_name, 'merged_entries'), \
('hidden', 'public')):
- % if entry.enum:
+ % if entry.enum and not (entry.typedef and entry.typedef.languages.get('java')):
${generate_enum(entry)}
% if entry.applied_visibility == 'hidden':
/**
* @hide
*/
%endif
- public static final Key<${jtype(entry)}> ${entry.get_name_minimal() | csym} =
+ public static final Key<${jtype_boxed(entry)}> ${entry.get_name_minimal() | csym} =
new ${entry.get_name_minimal() | pascal_case}Key("${entry.name}");
% else:
% if entry.applied_visibility == 'hidden':
@@ -132,8 +132,8 @@
* @hide
*/
%endif
- public static final Key<${jtype(entry)}> ${entry.get_name_minimal() | csym} =
- new Key<${jtype(entry)}>("${entry.name}", ${jclass(entry)});
+ public static final Key<${jtype_boxed(entry)}> ${entry.get_name_minimal() | csym} =
+ new Key<${jtype_boxed(entry)}>("${entry.name}", ${jclass(entry)});
% endif
% endfor
diff --git a/camera/docs/docs.html b/camera/docs/docs.html
index 50f98e5..49d2e3c 100644
--- a/camera/docs/docs.html
+++ b/camera/docs/docs.html
@@ -1066,7 +1066,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -1552,7 +1552,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -2034,7 +2034,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -4481,7 +4481,7 @@
<td class="entry_type">
<span class="entry_type_name">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as string]</span>
</td> <!-- entry_type -->
@@ -4657,7 +4657,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
</td> <!-- entry_type -->
@@ -4723,7 +4723,7 @@
<span class="entry_type_array">
2 x n
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
<div class="entry_type_notes">list of resolution pairs</div>
@@ -4860,7 +4860,7 @@
<td class="entry_type">
<span class="entry_type_name">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as string]</span>
</td> <!-- entry_type -->
@@ -5076,7 +5076,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
</td> <!-- entry_type -->
@@ -5575,7 +5575,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as size]</span>
<div class="entry_type_notes">width and height of geometric correction map</div>
@@ -5688,7 +5688,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
<div class="entry_type_notes">width and height of lens shading map provided by the HAL.<wbr> (N,<wbr> M)</div>
@@ -7108,7 +7108,7 @@
<span class="entry_type_array">
4
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as rectangle]</span>
</td> <!-- entry_type -->
@@ -7321,7 +7321,7 @@
<span class="entry_type_array">
n x 2
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
</td> <!-- entry_type -->
@@ -7439,7 +7439,7 @@
<span class="entry_type_array">
n x 2
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
</td> <!-- entry_type -->
@@ -7523,7 +7523,7 @@
<span class="entry_type_array">
n x 2
</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as size]</span>
</td> <!-- entry_type -->
@@ -7587,7 +7587,7 @@
<span class="entry_type_array">
4
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as rectangle]</span>
</td> <!-- entry_type -->
@@ -7836,7 +7836,7 @@
<span class="entry_type_array">
4
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as rectangle]</span>
<div class="entry_type_notes">Four ints defining the active pixel rectangle</div>
@@ -8051,7 +8051,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as size]</span>
<div class="entry_type_notes">width x height in millimeters</div>
@@ -8091,7 +8091,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as size]</span>
</td> <!-- entry_type -->
@@ -9198,7 +9198,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -9239,7 +9239,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -9528,7 +9528,7 @@
<span class="entry_type_array">
2
</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as size]</span>
<div class="entry_type_notes">width x height</div>
@@ -9726,7 +9726,7 @@
<span class="entry_type_array">
n x 4
</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as rectangle]</span>
<div class="entry_type_notes">(xmin,<wbr> ymin,<wbr> xmax,<wbr> ymax).<wbr> (0,<wbr>0) is top-left of active pixel area</div>
@@ -9842,7 +9842,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -9923,7 +9923,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [system]</span>
+ <span class="entry_type_visibility"> [system as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -10603,7 +10603,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [hidden]</span>
+ <span class="entry_type_visibility"> [hidden as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -10680,7 +10680,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [hidden]</span>
+ <span class="entry_type_visibility"> [hidden as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -10911,7 +10911,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as boolean]</span>
<ul class="entry_type_enum">
<li>
@@ -10989,7 +10989,7 @@
<td class="entry_type">
<span class="entry_type_name entry_type_name_enum">byte</span>
- <span class="entry_type_visibility"> [public]</span>
+ <span class="entry_type_visibility"> [public as boolean]</span>
<ul class="entry_type_enum">
<li>
diff --git a/camera/docs/html.mako b/camera/docs/html.mako
index 0994bcd..937e19c 100644
--- a/camera/docs/html.mako
+++ b/camera/docs/html.mako
@@ -242,7 +242,7 @@
% endfor
</ul>
% endif
- <span class="entry_type_visibility"> [${prop.applied_visibility}]</span>
+ <span class="entry_type_visibility"> [${prop.applied_visibility}${" as %s" %prop.typedef.name if prop.typedef else ""}]</span>
% if prop.type_notes is not None:
<div class="entry_type_notes">${prop.type_notes | wbr}</div>
% endif
diff --git a/camera/docs/metadata-generate b/camera/docs/metadata-generate
index 9b3a009..ef19343 100755
--- a/camera/docs/metadata-generate
+++ b/camera/docs/metadata-generate
@@ -77,7 +77,8 @@
git rev-parse --show-toplevel 2> /dev/null)"
if [[ $? -eq 0 ]]; then
# Both staged and unstaged changes
- local diff_result="$(git status --porcelain | egrep -c -v '^[?][?]')"
+ local diff_result="$(cd "$dir_path";
+ git status --porcelain | egrep -c -v '^[?][?]')"
echo "Diff result was $diff_result" >& /dev/null
echo "Diff result was $diff_result" >& /dev/null
if [[ $diff_result -eq 0 ]]; then
diff --git a/camera/docs/metadata-validate b/camera/docs/metadata-validate
index d507d8e..a7755ad 100755
--- a/camera/docs/metadata-validate
+++ b/camera/docs/metadata-validate
@@ -28,6 +28,6 @@
schema=$thisdir/metadata_properties.xsd
doc=$1
-xmllint --noout --schema $schema $out $doc || exit 1
+xmllint --noout --schema $schema $doc || exit 1
python $thisdir/metadata_validate.py $doc || exit 1
diff --git a/camera/docs/metadata_helpers.py b/camera/docs/metadata_helpers.py
index 97a9451..b8d1344 100644
--- a/camera/docs/metadata_helpers.py
+++ b/camera/docs/metadata_helpers.py
@@ -303,54 +303,122 @@
"""
return 'TYPE_%s' %(what.upper())
-def jtype(entry):
+
+# Calculate a java type name from an entry with a Typedef node
+def _jtypedef_type(entry):
+ typedef = entry.typedef
+ additional = ''
+
+ # Hacky way to deal with arrays. Assume that if we have
+ # size 'Constant x N' the Constant is part of the Typedef size.
+ # So something sized just 'Constant', 'Constant1 x Constant2', etc
+ # is not treated as a real java array.
+ if entry.container == 'array':
+ has_variable_size = False
+ for size in entry.container_sizes:
+ try:
+ size_int = int(size)
+ except ValueError:
+ has_variable_size = True
+
+ if has_variable_size:
+ additional = '[]'
+
+ try:
+ name = typedef.languages['java']
+
+ return "%s%s" %(name, additional)
+ except KeyError:
+ return None
+
+# Box if primitive. Otherwise leave unboxed.
+def _jtype_box(type_name):
+ mapping = {
+ 'boolean': 'Boolean',
+ 'byte': 'Byte',
+ 'int': 'Integer',
+ 'float': 'Float',
+ 'double': 'Double',
+ 'long': 'Long'
+ }
+
+ return mapping.get(type_name, type_name)
+
+def jtype_unboxed(entry):
+ """
+ Calculate the Java type from an entry type string, to be used whenever we
+ need the regular type in Java. It's not boxed, so it can't be used as a
+ generic type argument when the entry type happens to resolve to a primitive.
+
+ Remarks:
+ Since Java generics cannot be instantiated with primitives, this version
+ is not applicable in that case. Use jtype_boxed instead for that.
+
+ Returns:
+ The string representing the Java type.
+ """
+ if not isinstance(entry, metadata_model.Entry):
+ raise ValueError("Expected entry to be an instance of Entry")
+
+ metadata_type = entry.type
+
+ java_type = None
+
+ if entry.typedef:
+ typedef_name = _jtypedef_type(entry)
+ if typedef_name:
+ java_type = typedef_name # already takes into account arrays
+
+ if not java_type:
+ if not java_type and entry.enum:
+ name = entry.name
+
+ name_without_ons = entry.get_name_as_list()[1:]
+ base_type = ".".join([pascal_case(i) for i in name_without_ons]) + \
+ "Key.Enum"
+
+ else:
+ mapping = {
+ 'int32': 'int',
+ 'int64': 'long',
+ 'float': 'float',
+ 'double': 'double',
+ 'byte': 'byte',
+ 'rational': 'Rational'
+ }
+
+ base_type = mapping[metadata_type]
+
+ # Convert to array (enums, basic types)
+ if entry.container == 'array':
+ additional = '[]'
+ else:
+ additional = ''
+
+ java_type = '%s%s' %(base_type, additional)
+
+ # Now box this sucker.
+ return java_type
+
+def jtype_boxed(entry):
"""
Calculate the Java type from an entry type string, to be used as a generic
type argument in Java. The type is guaranteed to inherit from Object.
+ It will only box when absolutely necessary, i.e. int -> Integer[], but
+ int[] -> int[].
+
Remarks:
Since Java generics cannot be instantiated with primitives, this version
will use boxed types when absolutely required.
Returns:
- The string representing the Java type.
+ The string representing the boxed Java type.
"""
+ unboxed_type = jtype_unboxed(entry)
+ return _jtype_box(unboxed_type)
- if not isinstance(entry, metadata_model.Entry):
- raise ValueError("Expected entry to be an instance of Entry")
-
- primitive_type = entry.type
-
- if entry.enum:
- name = entry.name
-
- name_without_ons = entry.get_name_as_list()[1:]
- base_type = ".".join([pascal_case(i) for i in name_without_ons]) + \
- "Key.Enum"
- else:
- mapping = {
- 'int32': 'Integer',
- 'int64': 'Long',
- 'float': 'Float',
- 'double': 'Double',
- 'byte': 'Byte',
- 'rational': 'Rational'
- }
-
- base_type = mapping[primitive_type]
-
- if entry.container == 'array':
- additional = '[]'
-
- #unbox if it makes sense
- if primitive_type != 'rational' and not entry.enum:
- base_type = jtype_primitive(primitive_type)
- else:
- additional = ''
-
- return "%s%s" %(base_type, additional)
-
-def jtype_primitive(what):
+def _jtype_primitive(what):
"""
Calculate the Java type from an entry type string.
@@ -392,16 +460,8 @@
Returns:
The ClassName.class string
"""
- the_type = entry.type
- try:
- class_name = jtype_primitive(the_type)
- except ValueError as e:
- class_name = the_type
- if entry.container == 'array':
- class_name += "[]"
-
- return "%s.class" %class_name
+ return "%s.class" %jtype_unboxed(entry)
def jidentifier(what):
"""
diff --git a/camera/docs/metadata_model.py b/camera/docs/metadata_model.py
index 6b70288..66fe9d6 100644
--- a/camera/docs/metadata_model.py
+++ b/camera/docs/metadata_model.py
@@ -32,6 +32,7 @@
EnumValue: A class corresponding to a <value> element within an Enum
Metadata: Root node that also provides tree construction functionality.
Tag: A node corresponding to a top level <tag> element.
+ Typedef: A node corresponding to a <typedef> element under <types>.
"""
import sys
@@ -195,6 +196,7 @@
parent: An edge to the parent Node. This is always None for Metadata.
outer_namespaces: A sequence of immediate OuterNamespace children.
tags: A sequence of all Tag instances available in the graph.
+ types: An iterable of all Typedef instances available in the graph.
"""
def __init__(self):
@@ -214,6 +216,7 @@
self._parent = None
self._outer_namespaces = None
self._tags = []
+ self._types = []
@property
def outer_namespaces(self):
@@ -226,6 +229,10 @@
def tags(self):
return (i for i in self._tags)
+ @property
+ def types(self):
+ return (i for i in self._types)
+
def _get_properties(self):
for i in self._entries:
@@ -253,6 +260,33 @@
if not tag_ids:
self._tags.append(Tag(tag, self, description))
+ def insert_type(self, type_name, type_selector="typedef", **kwargs):
+ """
+ Insert a type into the metadata.
+
+ Args:
+ type_name: A type's name
+ type_selector: The selector for the type, e.g. 'typedef'
+
+ Args (if type_selector == 'typedef'):
+ languages: A map of 'language name' -> 'fully qualified class path'
+
+ Example:
+ metadata.insert_type('rectangle', 'typedef',
+ { 'java': 'android.graphics.Rect' })
+
+ Remarks:
+ Subsequent calls to insert_type with the same type name are safe (they
+ will be ignored)
+ """
+
+ if type_selector != 'typedef':
+ raise ValueError("Unsupported type_selector given " + type_selector)
+
+ type_names = [tp.name for tp in self.types if tp.name == tp]
+ if not type_names:
+ self._types.append(Typedef(type_name, self, kwargs.get('languages')))
+
def insert_entry(self, entry):
"""
Insert an entry into the metadata.
@@ -332,6 +366,8 @@
self.validate_tree()
self._construct_tags()
self.validate_tree()
+ self._construct_types()
+ self.validate_tree()
self._construct_clones()
self.validate_tree()
self._construct_outer_namespaces()
@@ -350,6 +386,16 @@
if p not in tag.entries:
tag._entries.append(p)
+ def _construct_types(self):
+ type_dict = self._dictionary_by_name(self.types)
+ for p in self._get_properties():
+ if p._type_name:
+ type_node = type_dict.get(p._type_name)
+ p._typedef = type_node
+
+ if p not in type_node.entries:
+ type_node._entries.append(p)
+
def _construct_clones(self):
for p in self._clones:
target_kind = p.target_kind
@@ -567,6 +613,36 @@
def _get_children(self):
return None
+class Typedef(Node):
+ """
+ A typedef Node corresponding to a <typedef> element under a top-level <types>.
+
+ Attributes (Read-Only):
+ name: The name of this typedef as a string.
+ languages: A dictionary of 'language name' -> 'fully qualified class'.
+ parent: An edge to the parent, which is always the Metadata root node.
+ entries: An iterable over all entries which reference this typedef.
+ """
+ def __init__(self, name, parent, languages=None):
+ self._name = name
+ self._parent = parent
+
+ # all entries that have this typedef
+ self._entries = [] # filled in by Metadata#construct_types
+
+ self._languages = languages or {}
+
+ @property
+ def languages(self):
+ return self._languages
+
+ @property
+ def entries(self):
+ return (i for i in self._entries)
+
+ def _get_children(self):
+ return None
+
class OuterNamespace(Node):
"""
A node corresponding to a <namespace> element under <metadata>
@@ -949,6 +1025,7 @@
units: A string units, or None.
tags: A sequence of Tag nodes associated with this Entry.
type_notes: A string describing notes for the type, or None.
+ typedef: A Typedef associated with this Entry, or None.
Remarks:
Subclass Clone can be used interchangeable with an Entry,
@@ -989,6 +1066,7 @@
type_notes: A string with the notes for the type
visibility: A string describing the visibility, eg 'system', 'hidden',
'public'
+ typedef: A string corresponding to a typedef's name attribute.
"""
if kwargs.get('type') is None:
@@ -1070,6 +1148,10 @@
return self._type_notes
@property
+ def typedef(self):
+ return self._typedef
+
+ @property
def enum(self):
return self._enum
@@ -1091,7 +1173,7 @@
def _init_common(self, **kwargs):
- self._parent = None # filled in by MetadataSet::_construct_entries
+ self._parent = None # filled in by Metadata::_construct_entries
self._container = kwargs.get('container')
self._container_sizes = kwargs.get('container_sizes')
@@ -1109,9 +1191,11 @@
self._notes = kwargs.get('notes')
self._tag_ids = kwargs.get('tag_ids', [])
- self._tags = None # Filled in by MetadataSet::_construct_tags
+ self._tags = None # Filled in by Metadata::_construct_tags
self._type_notes = kwargs.get('type_notes')
+ self._type_name = kwargs.get('type_name')
+ self._typedef = None # Filled in by Metadata::_construct_types
if kwargs.get('enum', False):
self._enum = Enum(self, enum_values, enum_ids, enum_optionals, enum_notes)
@@ -1312,7 +1396,8 @@
'tuple_values',
'type',
'type_notes',
- 'visibility'
+ 'visibility',
+ 'typedef'
]
for p in props_common:
diff --git a/camera/docs/metadata_parser_xml.py b/camera/docs/metadata_parser_xml.py
index 4e5c35f..f0ed12e 100755
--- a/camera/docs/metadata_parser_xml.py
+++ b/camera/docs/metadata_parser_xml.py
@@ -107,6 +107,15 @@
for tag in tags.find_all('tag'):
self.metadata.insert_tag(tag['id'], tag.string)
+ types = self.soup.types
+ if types is not None:
+ for tp in types.find_all('typedef'):
+ languages = {}
+ for lang in tp.find_all('language'):
+ languages[lang['name']] = lang.string
+
+ self.metadata.insert_type(tp['name'], 'typedef', languages=languages)
+
# add all entries, preserving the ordering of the XML file
# this is important for future ABI compatibility when generating code
entry_filter = lambda x: x.name == 'entry' or x.name == 'clone'
@@ -149,6 +158,11 @@
d['visibility'] = entry.get('visibility')
#
+ # Typedef
+ #
+ d['type_name'] = entry.get('typedef')
+
+ #
# Enum
#
if entry.get('enum', 'false') == 'true':
diff --git a/camera/docs/metadata_properties.xml b/camera/docs/metadata_properties.xml
index 77f7cc8..1e4fc17 100644
--- a/camera/docs/metadata_properties.xml
+++ b/camera/docs/metadata_properties.xml
@@ -40,6 +40,22 @@
Tag only used by camera device HAL 2.x
</tag>
</tags>
+
+ <types>
+ <typedef name="rectangle">
+ <language name="java">android.graphics.Rect</language>
+ </typedef>
+ <typedef name="size">
+ <language name="java">android.hardware.photography.Size</language>
+ </typedef>
+ <typedef name="string">
+ <language name="java">String</language>
+ </typedef>
+ <typedef name="boolean">
+ <language name="java">boolean</language>
+ </typedef>
+ </types>
+
<namespace name="android">
<section name="colorCorrection">
<controls>
@@ -130,7 +146,8 @@
compensation of -1</notes>
<tag id="BC" />
</entry>
- <entry name="aeLock" type="byte" visibility="public" enum="true">
+ <entry name="aeLock" type="byte" visibility="public" enum="true"
+ typedef="boolean">
<enum>
<value>OFF
<notes>Autoexposure lock is disabled; the AE algorithm
@@ -366,7 +383,8 @@
any active trigger, and return to initial AF state.</notes>
<tag id="BC" />
</entry>
- <entry name="awbLock" type="byte" visibility="public" enum="true">
+ <entry name="awbLock" type="byte" visibility="public" enum="true"
+ typedef="boolean">
<enum>
<value>OFF
<notes>Auto-whitebalance lock is disabled; the AWB
@@ -538,7 +556,7 @@
<tag id="BC" />
</entry>
<entry name="videoStabilizationMode" type="byte" visibility="public"
- enum="true">
+ enum="true" typedef="boolean">
<enum>
<value>OFF</value>
<value>ON</value>
@@ -1026,7 +1044,8 @@
<range>(-180 - 180], [-90,90], [-inf, inf]</range>
<tag id="BC" />
</entry>
- <entry name="gpsProcessingMethod" type="byte" visibility="public">
+ <entry name="gpsProcessingMethod" type="byte" visibility="public"
+ typedef="string">
<description>32 characters describing GPS algorithm to
include in EXIF</description>
<units>UTF-8 null-terminated string</units>
@@ -1059,7 +1078,7 @@
<tag id="BC" />
</entry>
<entry name="thumbnailSize" type="int32" visibility="public"
- container="array">
+ container="array" typedef="size">
<array>
<size>2</size>
</array>
@@ -1071,7 +1090,7 @@
</controls>
<static>
<entry name="availableThumbnailSizes" type="int32" visibility="public"
- type_notes="list of resolution pairs" container="array">
+ type_notes="list of resolution pairs" container="array" typedef="size">
<array>
<size>2</size>
<size>n</size>
@@ -1245,7 +1264,7 @@
</entry>
<entry name="geometricCorrectionMapSize" type="int32"
type_notes="width and height of geometric correction map"
- container="array">
+ container="array" typedef="size">
<array>
<size>2</size>
</array>
@@ -1273,8 +1292,8 @@
<tag id="V1" />
</entry>
<entry name="shadingMapSize" type="int32" visibility="public"
- type_notes="width and height of lens shading map provided by the HAL. (N, M)"
- container="array">
+ type_notes="width and height of lens shading map provided by the HAL. (N, M)"
+ container="array" typedef="size">
<array>
<size>2</size>
</array>
@@ -1566,7 +1585,7 @@
<section name="scaler">
<controls>
<entry name="cropRegion" type="int32" visibility="public"
- container="array">
+ container="array" typedef="rectangle">
<array>
<size>4</size>
</array>
@@ -1661,7 +1680,7 @@
<tag id="BC" />
</entry>
<entry name="availableJpegSizes" type="int32" visibility="public"
- container="array">
+ container="array" typedef="size">
<array>
<size>n</size>
<size>2</size>
@@ -1696,7 +1715,7 @@
<tag id="BC" />
</entry>
<entry name="availableProcessedSizes" type="int32" visibility="public"
- container="array">
+ container="array" typedef="size">
<array>
<size>n</size>
<size>2</size>
@@ -1725,7 +1744,7 @@
<tag id="BC" />
</entry>
<entry name="availableRawSizes" type="int32"
- container="array">
+ container="array" typedef="size">
<array>
<size>n</size>
<size>2</size>
@@ -1776,7 +1795,8 @@
<namespace name="info">
<entry name="activeArraySize" type="int32" visibility="public"
type_notes="Four ints defining the active pixel rectangle"
- container="array">
+ container="array"
+ typedef="rectangle">
<array>
<size>4</size>
</array>
@@ -1840,7 +1860,7 @@
</entry>
<entry name="physicalSize" type="float" visibility="public"
type_notes="width x height in millimeters"
- container="array">
+ container="array" typedef="size">
<array>
<size>2</size>
</array>
@@ -1851,7 +1871,7 @@
<tag id="BC" />
</entry>
<entry name="pixelArraySize" type="int32"
- container="array">
+ container="array" typedef="size">
<array>
<size>2</size>
</array>
@@ -2101,7 +2121,7 @@
android.statistics.info.availableFaceDetectModes.</notes>
<tag id="BC" />
</entry>
- <entry name="histogramMode" type="byte" enum="true">
+ <entry name="histogramMode" type="byte" enum="true" typedef="boolean">
<enum>
<value>OFF</value>
<value>ON</value>
@@ -2110,7 +2130,7 @@
generation</description>
<tag id="V1" />
</entry>
- <entry name="sharpnessMapMode" type="byte" enum="true">
+ <entry name="sharpnessMapMode" type="byte" enum="true" typedef="boolean">
<enum>
<value>OFF</value>
<value>ON</value>
@@ -2167,7 +2187,7 @@
region.</description>
</entry>
<entry name="sharpnessMapSize" type="int32"
- type_notes="width x height" container="array">
+ type_notes="width x height" container="array" typedef="size">
<array>
<size>2</size>
</array>
@@ -2203,7 +2223,7 @@
</entry>
<entry name="faceRectangles" type="int32" visibility="public"
type_notes="(xmin, ymin, xmax, ymax). (0,0) is top-left of active pixel area"
- container="array">
+ container="array" typedef="rectangle">
<array>
<size>n</size>
<size>4</size>
@@ -2407,7 +2427,8 @@
</section>
<section name="led">
<controls>
- <entry name="transmit" type="byte" visibility="hidden" enum="true">
+ <entry name="transmit" type="byte" visibility="hidden" enum="true"
+ typedef="boolean">
<enum>
<value>OFF</value>
<value>ON</value>
@@ -2471,7 +2492,8 @@
</section>
<section name="blackLevel">
<controls>
- <entry name="lock" type="byte" visibility="public" enum="true">
+ <entry name="lock" type="byte" visibility="public" enum="true"
+ typedef="boolean">
<enum>
<value>OFF</value>
<value>ON</value>
diff --git a/camera/docs/metadata_properties.xsd b/camera/docs/metadata_properties.xsd
index f567333..4e990bb 100644
--- a/camera/docs/metadata_properties.xsd
+++ b/camera/docs/metadata_properties.xsd
@@ -18,11 +18,23 @@
targetNamespace="http://schemas.android.com/service/camera/metadata/"
elementFormDefault="qualified">
- <element name="metadata" type="tns:MetadataType"></element>
+ <element name="metadata" type="tns:MetadataType">
+ <key name="TypeNameKey">
+ <selector xpath="tns:types/tns:typedef" />
+ <field xpath="@name" />
+ </key>
+
+ <!-- ensure that <entry typedef="..."> refers to a valid <typedef name='..."/> -->
+ <keyref name="TypeNameKeyRef" refer="tns:TypeNameKey">
+ <selector xpath=".//tns:entry" /> <!-- recursively find any descendant entry -->
+ <field xpath="@typedef" />
+ </keyref>
+ </element>
<complexType name="MetadataType">
<sequence>
<element name="tags" type="tns:TagsType" maxOccurs="1" minOccurs="0"></element>
+ <element name="types" type="tns:TypesType" maxOccurs="1" minOccurs="0"></element>
<element name="namespace" type="tns:NamespaceType"
maxOccurs="unbounded" minOccurs="1">
</element>
@@ -86,6 +98,36 @@
</simpleContent>
</complexType>
+ <complexType name="TypesType">
+ <sequence>
+ <element name="typedef" type="tns:TypedefType" maxOccurs="unbounded" minOccurs="0">
+ </element>
+ </sequence>
+ </complexType>
+
+ <complexType name="TypedefType">
+ <sequence>
+ <element name="language" type="tns:LanguageType" maxOccurs="unbounded" minOccurs="1"></element>
+ </sequence>
+ <attribute name="name" type="string" use="required" />
+ </complexType>
+
+ <complexType name="LanguageType">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="name" use="required">
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="java" />
+ <enumeration value="c" />
+ <enumeration value="c++" />
+ </restriction>
+ </simpleType>
+ </attribute>
+ </extension>
+ </simpleContent>
+ </complexType>
+
<group name="BaseEntryGroup">
<sequence>
<element name="description" type="string" maxOccurs="1"
@@ -155,6 +197,7 @@
</restriction>
</simpleType>
</attribute>
+ <attribute name="typedef" type="string" />
</complexType>
<complexType name="EnumType">
diff --git a/camera/docs/metadata_template.mako b/camera/docs/metadata_template.mako
index 2fee0a1..5c03d3d 100644
--- a/camera/docs/metadata_template.mako
+++ b/camera/docs/metadata_template.mako
@@ -29,6 +29,16 @@
% endfor
</tags>
+<types>
+% for typedef in metadata.types:
+ <typedef name="${typedef.name}">
+ % for (language, klass) in typedef.languages.iteritems():
+ <language name="${language}">${klass}</language>
+ % endfor
+ </typedef>
+% endfor
+</types>
+
% for root in metadata.outer_namespaces:
<namespace name="${root.name}">
% for section in root.sections:
@@ -84,6 +94,10 @@
% if prop.container is not None:
container="${prop.container}"
% endif
+
+ % if prop.typedef is not None:
+ typedef="${prop.typedef.name}"
+ % endif
>
% if prop.container == 'array':