OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2013 The Chromium Authors. All rights reserved. | 3 # Copyright 2013 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Convert Android xml resources to API 14 compatible. | 7 """Convert Android xml resources to API 14 compatible. |
8 | 8 |
9 There are two reasons that we cannot just use API 17 attributes, | 9 There are two reasons that we cannot just use API 17 attributes, |
10 so we are generating another set of resources by this script. | 10 so we are generating another set of resources by this script. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 if name in ATTRIBUTES_TO_MAP_REVERSED: | 69 if name in ATTRIBUTES_TO_MAP_REVERSED: |
70 print >> sys.stderr, ('warning: ' + filename + ' should use ' + | 70 print >> sys.stderr, ('warning: ' + filename + ' should use ' + |
71 ATTRIBUTES_TO_MAP_REVERSED[name] + | 71 ATTRIBUTES_TO_MAP_REVERSED[name] + |
72 ' instead of ' + name) | 72 ' instead of ' + name) |
73 elif name in GRAVITY_ATTRIBUTES and ('left' in value or 'right' in value): | 73 elif name in GRAVITY_ATTRIBUTES and ('left' in value or 'right' in value): |
74 print >> sys.stderr, ('warning: ' + filename + | 74 print >> sys.stderr, ('warning: ' + filename + |
75 ' should use start/end instead of left/right for ' + | 75 ' should use start/end instead of left/right for ' + |
76 name) | 76 name) |
77 | 77 |
78 | 78 |
79 def GenerateV14LayoutResource(dom, filename): | 79 def WriteDomToFile(dom, filename): |
| 80 """Write the given dom to filename.""" |
| 81 build_utils.MakeDirectory(os.path.dirname(filename)) |
| 82 with open(filename, 'w') as f: |
| 83 dom.writexml(f, '', ' ', '\n', encoding='utf-8') |
| 84 |
| 85 |
| 86 def HasStyleResource(dom): |
| 87 """Return True if the dom is a style resource, False otherwise.""" |
| 88 root_node = IterateXmlElements(dom).next() |
| 89 return bool(root_node.nodeName == 'resources' and |
| 90 list(root_node.getElementsByTagName('style'))) |
| 91 |
| 92 |
| 93 def ErrorIfStyleResourceExistsInDir(input_dir): |
| 94 """If a style resource is in input_dir, exist with an error message.""" |
| 95 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): |
| 96 dom = minidom.parse(input_filename) |
| 97 if HasStyleResource(dom): |
| 98 raise Exception('error: style file ' + input_filename + |
| 99 ' should be under ' + input_dir + |
| 100 '-v17 directory. Please refer to crbug.com/243952 ' |
| 101 'for the details.') |
| 102 |
| 103 |
| 104 def GenerateV14LayoutResourceDom(dom, filename): |
80 """Convert layout resource to API 14 compatible layout resource. | 105 """Convert layout resource to API 14 compatible layout resource. |
81 | 106 |
82 Args: | 107 Args: |
83 dom: parsed minidom object to be modified. | 108 dom: parsed minidom object to be modified. |
84 filename: file name to display in case we print warnings. | 109 filename: file name to display in case we print warnings. |
85 Returns: | 110 Returns: |
86 True if dom is modified, False otherwise. | 111 True if dom is modified, False otherwise. |
87 """ | 112 """ |
88 is_modified = False | 113 is_modified = False |
89 | 114 |
90 # Iterate all the elements' attributes to find attributes to convert. | 115 # Iterate all the elements' attributes to find attributes to convert. |
91 for element in IterateXmlElements(dom): | 116 for element in IterateXmlElements(dom): |
92 for name, value in list(element.attributes.items()): | 117 for name, value in list(element.attributes.items()): |
93 # Convert any API 17 Start/End attributes to Left/Right attributes. | 118 # Convert any API 17 Start/End attributes to Left/Right attributes. |
94 # For example, from paddingStart="10dp" to paddingLeft="10dp" | 119 # For example, from paddingStart="10dp" to paddingLeft="10dp" |
95 # Note: gravity attributes are not necessary to convert because | 120 # Note: gravity attributes are not necessary to convert because |
96 # start/end values are backward-compatible. Explained at | 121 # start/end values are backward-compatible. Explained at |
97 # https://plus.sandbox.google.com/+RomanNurik/posts/huuJd8iVVXY?e=Showroom | 122 # https://plus.sandbox.google.com/+RomanNurik/posts/huuJd8iVVXY?e=Showroom |
98 if name in ATTRIBUTES_TO_MAP: | 123 if name in ATTRIBUTES_TO_MAP: |
99 element.setAttribute(ATTRIBUTES_TO_MAP[name], value) | 124 element.setAttribute(ATTRIBUTES_TO_MAP[name], value) |
100 del element.attributes[name] | 125 del element.attributes[name] |
101 is_modified = True | 126 is_modified = True |
102 else: | 127 else: |
103 WarnIfDeprecatedAttribute(name, value, filename) | 128 WarnIfDeprecatedAttribute(name, value, filename) |
104 | 129 |
105 return is_modified | 130 return is_modified |
106 | 131 |
107 | 132 |
108 def GenerateV14StyleResource(dom, filename): | 133 def GenerateV14StyleResourceDom(dom, filename): |
109 """Convert style resource to API 14 compatible style resource. | 134 """Convert style resource to API 14 compatible style resource. |
110 | 135 |
111 Args: | 136 Args: |
112 dom: parsed minidom object to be modified. | 137 dom: parsed minidom object to be modified. |
113 filename: file name to display in case we print warnings. | 138 filename: file name to display in case we print warnings. |
114 Returns: | |
115 True if dom is modified, False otherwise. | |
116 """ | 139 """ |
117 is_modified = False | |
118 | |
119 for style_element in dom.getElementsByTagName('style'): | 140 for style_element in dom.getElementsByTagName('style'): |
120 for item_element in style_element.getElementsByTagName('item'): | 141 for item_element in style_element.getElementsByTagName('item'): |
121 name = item_element.attributes['name'].value | 142 name = item_element.attributes['name'].value |
122 value = item_element.childNodes[0].nodeValue | 143 value = item_element.childNodes[0].nodeValue |
123 if name in ATTRIBUTES_TO_MAP: | 144 if name in ATTRIBUTES_TO_MAP: |
124 item_element.attributes['name'].value = ATTRIBUTES_TO_MAP[name] | 145 item_element.attributes['name'].value = ATTRIBUTES_TO_MAP[name] |
125 is_modified = True | |
126 else: | 146 else: |
127 WarnIfDeprecatedAttribute(name, value, filename) | 147 WarnIfDeprecatedAttribute(name, value, filename) |
128 | 148 |
129 return is_modified | |
130 | 149 |
131 | 150 def GenerateV14LayoutResource(input_filename, output_v14_filename, |
132 def GenerateV14Resource(input_filename, | 151 output_v17_filename): |
133 output_v14_filename, | 152 """Convert API 17 layout resource to API 14 compatible layout resource. |
134 output_v17_filename): | |
135 """Convert layout/style resource to API 14 compatible layout/style resource. | |
136 | 153 |
137 It's mostly a simple replacement, s/Start/Left s/End/Right, | 154 It's mostly a simple replacement, s/Start/Left s/End/Right, |
138 on the attribute names. | 155 on the attribute names. |
139 If the generated resource is identical to the original resource, | 156 If the generated resource is identical to the original resource, |
140 don't do anything. If not, write the generated resource to | 157 don't do anything. If not, write the generated resource to |
141 output_v14_filename, and copy the original resource to output_v17_filename. | 158 output_v14_filename, and copy the original resource to output_v17_filename. |
142 """ | 159 """ |
143 dom = minidom.parse(input_filename) | 160 dom = minidom.parse(input_filename) |
144 | 161 is_modified = GenerateV14LayoutResourceDom(dom, input_filename) |
145 root_node = IterateXmlElements(dom).next() | |
146 if root_node.nodeName == 'resources': | |
147 # Style resources are under 'values*/' directory. | |
148 is_modified = GenerateV14StyleResource(dom, input_filename) | |
149 else: | |
150 # Layout resources can be under 'layout*/' or 'xml*/' directory. | |
151 is_modified = GenerateV14LayoutResource(dom, input_filename) | |
152 | 162 |
153 if is_modified: | 163 if is_modified: |
154 # Write the generated resource. | 164 # Write the generated resource. |
155 build_utils.MakeDirectory(os.path.dirname(output_v14_filename)) | 165 WriteDomToFile(dom, output_v14_filename) |
156 with open(output_v14_filename, 'w') as f: | |
157 dom.writexml(f, '', ' ', '\n', encoding='utf-8') | |
158 | 166 |
159 # Copy the original resource. | 167 # Copy the original resource. |
160 build_utils.MakeDirectory(os.path.dirname(output_v17_filename)) | 168 build_utils.MakeDirectory(os.path.dirname(output_v17_filename)) |
161 shutil.copy2(input_filename, output_v17_filename) | 169 shutil.copy2(input_filename, output_v17_filename) |
162 | 170 |
163 | 171 |
164 def GenerateV14XmlResourcesInDir(input_dir, output_v14_dir, output_v17_dir): | 172 def GenerateV14StyleResource(input_filename, output_v14_filename): |
165 """Convert resources to API 14 compatible XML resources in the directory.""" | 173 """Convert API 17 style resources to API 14 compatible style resource. |
| 174 |
| 175 Write the generated style resource to output_v14_filename. |
| 176 It's mostly a simple replacement, s/Start/Left s/End/Right, |
| 177 on the attribute names. |
| 178 """ |
| 179 dom = minidom.parse(input_filename) |
| 180 GenerateV14StyleResourceDom(dom, input_filename) |
| 181 |
| 182 # Write the generated resource. |
| 183 WriteDomToFile(dom, output_v14_filename) |
| 184 |
| 185 |
| 186 def GenerateV14LayoutResourcesInDir(input_dir, output_v14_dir, output_v17_dir): |
| 187 """Convert layout resources to API 14 compatible resources in input_dir.""" |
166 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): | 188 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): |
167 rel_filename = os.path.relpath(input_filename, input_dir) | 189 rel_filename = os.path.relpath(input_filename, input_dir) |
168 output_v14_filename = os.path.join(output_v14_dir, rel_filename) | 190 output_v14_filename = os.path.join(output_v14_dir, rel_filename) |
169 output_v17_filename = os.path.join(output_v17_dir, rel_filename) | 191 output_v17_filename = os.path.join(output_v17_dir, rel_filename) |
170 GenerateV14Resource(input_filename, output_v14_filename, | 192 GenerateV14LayoutResource(input_filename, output_v14_filename, |
171 output_v17_filename) | 193 output_v17_filename) |
| 194 |
| 195 |
| 196 def GenerateV14StyleResourcesInDir(input_dir, output_v14_dir): |
| 197 """Convert style resources to API 14 compatible resources in input_dir.""" |
| 198 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): |
| 199 rel_filename = os.path.relpath(input_filename, input_dir) |
| 200 output_v14_filename = os.path.join(output_v14_dir, rel_filename) |
| 201 GenerateV14StyleResource(input_filename, output_v14_filename) |
172 | 202 |
173 | 203 |
174 def ParseArgs(): | 204 def ParseArgs(): |
175 """Parses command line options. | 205 """Parses command line options. |
176 | 206 |
177 Returns: | 207 Returns: |
178 An options object as from optparse.OptionsParser.parse_args() | 208 An options object as from optparse.OptionsParser.parse_args() |
179 """ | 209 """ |
180 parser = optparse.OptionParser() | 210 parser = optparse.OptionParser() |
181 parser.add_option('--res-dir', | 211 parser.add_option('--res-dir', |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 if 'ldrtl' in qualifiers: | 245 if 'ldrtl' in qualifiers: |
216 continue | 246 continue |
217 | 247 |
218 # We also need to copy the original v17 resource to *-v17 directory | 248 # We also need to copy the original v17 resource to *-v17 directory |
219 # because the generated v14 resource will hide the original resource. | 249 # because the generated v14 resource will hide the original resource. |
220 input_dir = os.path.join(options.res_dir, name) | 250 input_dir = os.path.join(options.res_dir, name) |
221 output_v14_dir = os.path.join(options.res_v14_compatibility_dir, name) | 251 output_v14_dir = os.path.join(options.res_v14_compatibility_dir, name) |
222 output_v17_dir = os.path.join(options.res_v14_compatibility_dir, name + | 252 output_v17_dir = os.path.join(options.res_v14_compatibility_dir, name + |
223 '-v17') | 253 '-v17') |
224 | 254 |
225 # We only convert resources under layout*/, xml*/, | 255 # We only convert layout resources under layout*/, xml*/, |
226 # and style resources under values*/. | 256 # and style resources under values*/. |
227 # TODO(kkimlabs): don't process xml directly once all layouts have | 257 # TODO(kkimlabs): don't process xml directly once all layouts have |
228 # been moved out of XML directory. see http://crbug.com/238458 | 258 # been moved out of XML directory. see http://crbug.com/238458 |
229 if resource_type in ('layout', 'xml', 'values'): | 259 if resource_type in ('layout', 'xml'): |
230 GenerateV14XmlResourcesInDir(input_dir, output_v14_dir, output_v17_dir) | 260 GenerateV14LayoutResourcesInDir(input_dir, output_v14_dir, output_v17_dir) |
| 261 elif resource_type == 'values': |
| 262 if 'v17' in qualifiers: |
| 263 output_qualifiers = qualifiers[:] |
| 264 del output_qualifiers[qualifiers.index('v17')] |
| 265 output_v14_dir = os.path.join(options.res_v14_compatibility_dir, |
| 266 '-'.join([resource_type] + |
| 267 output_qualifiers)) |
| 268 GenerateV14StyleResourcesInDir(input_dir, output_v14_dir) |
| 269 else: |
| 270 # TODO(kkimlabs): uncomment the below line and remove 'pass' once the |
| 271 # downstream fix (https://gerrit-int.chromium.org/#/c/38786/) is landed. |
| 272 # ErrorIfStyleResourceExistsInDir(input_dir) |
| 273 pass |
231 | 274 |
232 if options.stamp: | 275 if options.stamp: |
233 build_utils.Touch(options.stamp) | 276 build_utils.Touch(options.stamp) |
234 | 277 |
235 if __name__ == '__main__': | 278 if __name__ == '__main__': |
236 sys.exit(main(sys.argv)) | 279 sys.exit(main(sys.argv)) |
237 | 280 |
OLD | NEW |