Camera2: Fix metadata XML to maintain ordering: DO NOT MERGE
Change-Id: I69adfbb1010b5f624d3ee618a1a45e0be510ca31
diff --git a/camera/docs/metadata_helpers.py b/camera/docs/metadata_helpers.py
index 1a01dff..35e9ba4 100644
--- a/camera/docs/metadata_helpers.py
+++ b/camera/docs/metadata_helpers.py
@@ -19,6 +19,7 @@
"""
import metadata_model
+from collections import OrderedDict
_context_buf = None
@@ -76,7 +77,7 @@
not isinstance(node, metadata_model.InnerNamespace):
raise TypeError("expected node to be a Section or InnerNamespace")
- d = {}
+ d = OrderedDict()
# 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 \
diff --git a/camera/docs/metadata_model.py b/camera/docs/metadata_model.py
index 1acf2b5..e91fcd1 100644
--- a/camera/docs/metadata_model.py
+++ b/camera/docs/metadata_model.py
@@ -34,6 +34,7 @@
"""
import sys
+from collections import OrderedDict
class Node(object):
"""
@@ -152,7 +153,7 @@
@staticmethod
def _dictionary_by_name(values):
- d = {}
+ d = OrderedDict()
for i in values:
d[i.name] = i
@@ -205,6 +206,7 @@
self._entries = []
# kind => { name => entry }
self._entry_map = { 'static': {}, 'dynamic': {}, 'controls': {} }
+ self._entries_ordered = [] # list of ordered Entry/Clone instances
self._clones = []
# Public (Read Only)
@@ -265,6 +267,7 @@
e = Entry(**entry)
self._entries.append(e)
self._entry_map[e.kind][e.name] = e
+ self._entries_ordered.append(e)
def insert_clone(self, clone):
"""
@@ -285,6 +288,7 @@
c = Clone(entry, **clone)
self._entry_map[c.kind][c.name] = c
self._clones.append(c)
+ self._entries_ordered.append(c)
def prune_clones(self):
"""
@@ -311,6 +315,7 @@
# remove from global list
self._clones.remove(p)
self._entry_map[p.kind].pop(p.name)
+ self._entries_ordered.remove(p)
# After all entries/clones are inserted,
@@ -367,7 +372,7 @@
for ons_name, ons in root.iteritems():
ons._leafs = []
- for p in self._get_properties():
+ for p in self._entries_ordered:
ons_name = p.get_outer_namespace()
ons = root.get(ons_name, OuterNamespace(ons_name, self))
root[ons_name] = ons
@@ -380,7 +385,6 @@
ons.validate_tree()
self._construct_sections(ons)
- ons.sort_children()
if ons not in self._outer_namespaces:
self._outer_namespaces.append(ons)
@@ -414,7 +418,6 @@
%(sec)
self._construct_kinds(sec)
- sec.sort_children()
if sec not in outer_namespace.sections:
outer_namespace._sections.append(sec)
@@ -457,7 +460,6 @@
self._construct_inner_namespaces(kind)
kind.validate_tree()
self._construct_entries(kind)
- kind.sort_children()
kind.validate_tree()
if kind not in section.kinds:
@@ -495,7 +497,6 @@
ins.validate_tree()
# construct children entries
self._construct_entries(ins, depth + 1)
- ins.sort_children()
if ins not in parent.namespaces:
parent._namespaces.append(ins)
diff --git a/camera/docs/metadata_parser_xml.py b/camera/docs/metadata_parser_xml.py
index a9ee25f..cadbac1 100755
--- a/camera/docs/metadata_parser_xml.py
+++ b/camera/docs/metadata_parser_xml.py
@@ -107,34 +107,36 @@
for tag in tags.find_all('tag'):
self.metadata.insert_tag(tag['id'], tag.string)
- for entry in self.soup.find_all("entry"):
- d = {
- 'name': fully_qualified_name(entry),
- 'type': entry['type'],
- 'kind': find_kind(entry),
- 'type_notes': entry.attrs.get('type_notes')
- }
+ # 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'
+ for entry in self.soup.find_all(entry_filter):
+ if entry.name == 'entry':
+ d = {
+ 'name': fully_qualified_name(entry),
+ 'type': entry['type'],
+ 'kind': find_kind(entry),
+ 'type_notes': entry.attrs.get('type_notes')
+ }
- d2 = self._parse_entry(entry)
+ d2 = self._parse_entry(entry)
+ insert = self.metadata.insert_entry
+ else:
+ d = {
+ 'name': entry['entry'],
+ 'kind': find_kind(entry),
+ 'target_kind': entry['kind'],
+ # no type since its the same
+ # no type_notes since its the same
+ }
+ d2 = {}
+
+ insert = self.metadata.insert_clone
+
d3 = self._parse_entry_optional(entry)
entry_dict = dict(d.items() + d2.items() + d3.items())
- self.metadata.insert_entry(entry_dict)
-
- entry = None
-
- for clone in self.soup.find_all("clone"):
- d = {
- 'name': clone['entry'],
- 'kind': find_kind(clone),
- 'target_kind': clone['kind'],
- # no type since its the same
- # no type_notes since its the same
- }
-
- d2 = self._parse_entry_optional(clone)
- clone_dict = dict(d.items() + d2.items())
- self.metadata.insert_clone(clone_dict)
+ insert(entry_dict)
self.metadata.construct_graph()