blob: 81f9c61a898955de4e567d19f47d33e81a254552 [file] [log] [blame]
Colin Cross72119102019-05-20 13:14:18 -07001#!/usr/bin/env python
2#
3# Copyright (C) 2018 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
Jaewoong Junge5cd4e12019-11-22 14:34:55 -080017"""A tool for inserting values from the build system into a manifest or a test config."""
Colin Cross72119102019-05-20 13:14:18 -070018
19from __future__ import print_function
20from xml.dom import minidom
21
22
23android_ns = 'http://schemas.android.com/apk/res/android'
24
25
26def get_children_with_tag(parent, tag_name):
27 children = []
28 for child in parent.childNodes:
29 if child.nodeType == minidom.Node.ELEMENT_NODE and \
30 child.tagName == tag_name:
31 children.append(child)
32 return children
33
34
35def find_child_with_attribute(element, tag_name, namespace_uri,
36 attr_name, value):
37 for child in get_children_with_tag(element, tag_name):
38 attr = child.getAttributeNodeNS(namespace_uri, attr_name)
39 if attr is not None and attr.value == value:
40 return child
41 return None
42
43
44def parse_manifest(doc):
45 """Get the manifest element."""
46
47 manifest = doc.documentElement
48 if manifest.tagName != 'manifest':
49 raise RuntimeError('expected manifest tag at root')
50 return manifest
51
52
53def ensure_manifest_android_ns(doc):
54 """Make sure the manifest tag defines the android namespace."""
55
56 manifest = parse_manifest(doc)
57
58 ns = manifest.getAttributeNodeNS(minidom.XMLNS_NAMESPACE, 'android')
59 if ns is None:
60 attr = doc.createAttributeNS(minidom.XMLNS_NAMESPACE, 'xmlns:android')
61 attr.value = android_ns
62 manifest.setAttributeNode(attr)
63 elif ns.value != android_ns:
64 raise RuntimeError('manifest tag has incorrect android namespace ' +
65 ns.value)
66
67
Jaewoong Junge5cd4e12019-11-22 14:34:55 -080068def parse_test_config(doc):
69 """ Get the configuration element. """
70
71 test_config = doc.documentElement
72 if test_config.tagName != 'configuration':
73 raise RuntimeError('expected configuration tag at root')
74 return test_config
75
76
Colin Cross72119102019-05-20 13:14:18 -070077def as_int(s):
78 try:
79 i = int(s)
80 except ValueError:
81 return s, False
82 return i, True
83
84
85def compare_version_gt(a, b):
86 """Compare two SDK versions.
87
88 Compares a and b, treating codenames like 'Q' as higher
89 than numerical versions like '28'.
90
91 Returns True if a > b
92
93 Args:
94 a: value to compare
95 b: value to compare
96 Returns:
97 True if a is a higher version than b
98 """
99
100 a, a_is_int = as_int(a.upper())
101 b, b_is_int = as_int(b.upper())
102
103 if a_is_int == b_is_int:
104 # Both are codenames or both are versions, compare directly
105 return a > b
106 else:
107 # One is a codename, the other is not. Return true if
108 # b is an integer version
109 return b_is_int
110
111
112def get_indent(element, default_level):
113 indent = ''
114 if element is not None and element.nodeType == minidom.Node.TEXT_NODE:
115 text = element.nodeValue
116 indent = text[:len(text)-len(text.lstrip())]
117 if not indent or indent == '\n':
118 # 1 indent = 4 space
119 indent = '\n' + (' ' * default_level * 4)
120 return indent
121
122
123def write_xml(f, doc):
124 f.write('<?xml version="1.0" encoding="utf-8"?>\n')
125 for node in doc.childNodes:
Cole Faustc41dd722021-11-09 15:08:26 -0800126 f.write(node.toxml() + '\n')