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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 224 |
225 | 225 |
226 def GenerateV14StyleResourcesInDir(input_dir, output_v14_dir): | 226 def GenerateV14StyleResourcesInDir(input_dir, output_v14_dir): |
227 """Convert style resources to API 14 compatible resources in input_dir.""" | 227 """Convert style resources to API 14 compatible resources in input_dir.""" |
228 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): | 228 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): |
229 rel_filename = os.path.relpath(input_filename, input_dir) | 229 rel_filename = os.path.relpath(input_filename, input_dir) |
230 output_v14_filename = os.path.join(output_v14_dir, rel_filename) | 230 output_v14_filename = os.path.join(output_v14_dir, rel_filename) |
231 GenerateV14StyleResource(input_filename, output_v14_filename) | 231 GenerateV14StyleResource(input_filename, output_v14_filename) |
232 | 232 |
233 | 233 |
234 def VerifyV14ResourcesInDir(input_dir, resource_type): | |
235 """Verify that the resources in input_dir is compatible with v14, i.e., they | |
236 don't use attributes that cause crashes on certain devices. Print an error if | |
237 they have.""" | |
238 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): | |
239 exception_message = ('error : ' + input_filename + ' has an RTL attribute, ' | |
240 'i.e., attribute that has "start" or "end" in its name.' | |
241 ' Pre-v17 resources should not include it because it ' | |
242 'can cause crashes on certain devices. Please refer to ' | |
243 'http://crbug.com/243952 for the details.') | |
244 dom = ParseAndReportErrors(input_filename) | |
245 if resource_type in ('layout', 'xml'): | |
246 if GenerateV14LayoutResourceDom(dom, input_filename, False): | |
247 raise Exception(exception_message) | |
248 elif resource_type == 'values': | |
249 if GenerateV14StyleResourceDom(dom, input_filename, False): | |
250 raise Exception(exception_message) | |
251 | |
252 | |
253 def AssertNoDeprecatedAttributesInDir(input_dir, resource_type): | |
254 """Raises an exception if resources in input_dir have deprecated attributes, | |
255 e.g., paddingLeft, paddingRight""" | |
256 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'): | |
257 dom = ParseAndReportErrors(input_filename) | |
258 if resource_type in ('layout', 'xml'): | |
259 GenerateV14LayoutResourceDom(dom, input_filename) | |
260 elif resource_type == 'values': | |
261 GenerateV14StyleResourceDom(dom, input_filename) | |
262 | |
263 | |
264 def ParseArgs(): | 234 def ParseArgs(): |
265 """Parses command line options. | 235 """Parses command line options. |
266 | 236 |
267 Returns: | 237 Returns: |
268 An options object as from optparse.OptionsParser.parse_args() | 238 An options object as from optparse.OptionsParser.parse_args() |
269 """ | 239 """ |
270 parser = optparse.OptionParser() | 240 parser = optparse.OptionParser() |
271 parser.add_option('--res-dir', | 241 parser.add_option('--res-dir', |
272 help='directory containing resources ' | 242 help='directory containing resources ' |
273 'used to generate v14 compatible resources') | 243 'used to generate v14 compatible resources') |
274 parser.add_option('--res-v14-compatibility-dir', | 244 parser.add_option('--res-v14-compatibility-dir', |
275 help='output directory into which ' | 245 help='output directory into which ' |
276 'v14 compatible resources will be generated') | 246 'v14 compatible resources will be generated') |
277 parser.add_option('--stamp', help='File to touch on success') | 247 parser.add_option('--stamp', help='File to touch on success') |
278 parser.add_option('--verify-only', action="store_true", help='Do not generate' | |
279 ' v14 resources. Instead, just verify that the resources are already ' | |
280 "compatible with v14, i.e. they don't use attributes that cause crashes " | |
281 'on certain devices.') | |
282 | 248 |
283 options, args = parser.parse_args() | 249 options, args = parser.parse_args() |
284 | 250 |
285 if args: | 251 if args: |
286 parser.error('No positional arguments should be given.') | 252 parser.error('No positional arguments should be given.') |
287 | 253 |
288 # Check that required options have been provided. | 254 # Check that required options have been provided. |
289 required_options = ('res_dir', 'res_v14_compatibility_dir') | 255 required_options = ('res_dir', 'res_v14_compatibility_dir') |
290 build_utils.CheckOptions(options, parser, required=required_options) | 256 build_utils.CheckOptions(options, parser, required=required_options) |
291 return options | 257 return options |
292 | 258 |
293 def GenerateV14Resources(res_dir, res_v14_dir, verify_only): | 259 def GenerateV14Resources(res_dir, res_v14_dir): |
294 for name in os.listdir(res_dir): | 260 for name in os.listdir(res_dir): |
295 if not os.path.isdir(os.path.join(res_dir, name)): | 261 if not os.path.isdir(os.path.join(res_dir, name)): |
296 continue | 262 continue |
297 | 263 |
298 dir_pieces = name.split('-') | 264 dir_pieces = name.split('-') |
299 resource_type = dir_pieces[0] | 265 resource_type = dir_pieces[0] |
300 qualifiers = dir_pieces[1:] | 266 qualifiers = dir_pieces[1:] |
301 | 267 |
302 api_level_qualifier_index = -1 | 268 api_level_qualifier_index = -1 |
303 api_level_qualifier = '' | 269 api_level_qualifier = '' |
304 for index, qualifier in enumerate(qualifiers): | 270 for index, qualifier in enumerate(qualifiers): |
305 if re.match('v[0-9]+$', qualifier): | 271 if re.match('v[0-9]+$', qualifier): |
306 api_level_qualifier_index = index | 272 api_level_qualifier_index = index |
307 api_level_qualifier = qualifier | 273 api_level_qualifier = qualifier |
308 break | 274 break |
309 | 275 |
310 # Android pre-v17 API doesn't support RTL. Skip. | 276 # Android pre-v17 API doesn't support RTL. Skip. |
311 if 'ldrtl' in qualifiers: | 277 if 'ldrtl' in qualifiers: |
312 continue | 278 continue |
313 | 279 |
314 input_dir = os.path.abspath(os.path.join(res_dir, name)) | 280 input_dir = os.path.abspath(os.path.join(res_dir, name)) |
315 | 281 |
316 if verify_only: | 282 # We also need to copy the original v17 resource to *-v17 directory |
317 if not api_level_qualifier or int(api_level_qualifier[1:]) < 17: | 283 # because the generated v14 resource will hide the original resource. |
318 VerifyV14ResourcesInDir(input_dir, resource_type) | 284 output_v14_dir = os.path.join(res_v14_dir, name) |
319 else: | 285 output_v17_dir = os.path.join(res_v14_dir, name + '-v17') |
320 AssertNoDeprecatedAttributesInDir(input_dir, resource_type) | |
321 else: | |
322 # We also need to copy the original v17 resource to *-v17 directory | |
323 # because the generated v14 resource will hide the original resource. | |
324 output_v14_dir = os.path.join(res_v14_dir, name) | |
325 output_v17_dir = os.path.join(res_v14_dir, name + '-v17') | |
326 | 286 |
327 # We only convert layout resources under layout*/, xml*/, | 287 # We only convert layout resources under layout*/, xml*/, |
328 # and style resources under values*/. | 288 # and style resources under values*/. |
329 if resource_type in ('layout', 'xml'): | 289 if resource_type in ('layout', 'xml'): |
330 if not api_level_qualifier: | 290 if not api_level_qualifier: |
331 GenerateV14LayoutResourcesInDir(input_dir, output_v14_dir, | 291 GenerateV14LayoutResourcesInDir(input_dir, output_v14_dir, |
332 output_v17_dir) | 292 output_v17_dir) |
333 elif resource_type == 'values': | 293 elif resource_type == 'values': |
334 if api_level_qualifier == 'v17': | 294 if api_level_qualifier == 'v17': |
335 output_qualifiers = qualifiers[:] | 295 output_qualifiers = qualifiers[:] |
336 del output_qualifiers[api_level_qualifier_index] | 296 del output_qualifiers[api_level_qualifier_index] |
337 output_v14_dir = os.path.join(res_v14_dir, | 297 output_v14_dir = os.path.join(res_v14_dir, |
338 '-'.join([resource_type] + | 298 '-'.join([resource_type] + |
339 output_qualifiers)) | 299 output_qualifiers)) |
340 GenerateV14StyleResourcesInDir(input_dir, output_v14_dir) | 300 GenerateV14StyleResourcesInDir(input_dir, output_v14_dir) |
341 elif not api_level_qualifier: | 301 elif not api_level_qualifier: |
342 ErrorIfStyleResourceExistsInDir(input_dir) | 302 ErrorIfStyleResourceExistsInDir(input_dir) |
343 | 303 |
344 def main(): | 304 def main(): |
345 options = ParseArgs() | 305 options = ParseArgs() |
346 | 306 |
347 res_v14_dir = options.res_v14_compatibility_dir | 307 res_v14_dir = options.res_v14_compatibility_dir |
348 | 308 |
349 build_utils.DeleteDirectory(res_v14_dir) | 309 build_utils.DeleteDirectory(res_v14_dir) |
350 build_utils.MakeDirectory(res_v14_dir) | 310 build_utils.MakeDirectory(res_v14_dir) |
351 | 311 |
352 GenerateV14Resources(options.res_dir, res_v14_dir, options.verify_only) | 312 GenerateV14Resources(options.res_dir, res_v14_dir) |
353 | 313 |
354 if options.stamp: | 314 if options.stamp: |
355 build_utils.Touch(options.stamp) | 315 build_utils.Touch(options.stamp) |
356 | 316 |
357 if __name__ == '__main__': | 317 if __name__ == '__main__': |
358 sys.exit(main()) | 318 sys.exit(main()) |
359 | 319 |
OLD | NEW |