Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Side by Side Diff: build/android/gyp/generate_v14_resources.py

Issue 14812015: [Android] Auto-generate only necessary v14 resources. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: (newt's comment) added 'compatible' on comment Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/android/gyp/generate_v14_compatible_resources.py ('k') | build/java.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
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
5 # found in the LICENSE file.
6
7 """Convert Android xml resources to API 14 compatible.
8
9 There are two reasons that we cannot just use API attributes,
10 so we are generating another set of resources by this script.
11
12 1. paddingStart attribute can cause a crash on Galaxy Tab 2.
13 2. There is a bug that paddingStart does not override paddingLeft on
14 JB-MR1. This is fixed on JB-MR2.
15
16 Therefore, this resource generation script can be removed when
17 we drop the support for JB-MR1.
18
19 Please refer to http://crbug.com/235118 for the details.
20 """
21
22 import optparse
23 import os
24 import re
25 import sys
26 import xml.dom.minidom as minidom
27
28 from util import build_utils
29
30 # Note that we are assuming 'android:' is an alias of
31 # the namespace 'http://schemas.android.com/apk/res/android'.
32
33 GRAVITY_ATTRIBUTES = ('android:gravity', 'android:layout_gravity')
34
35 # Almost all the attributes that has "Start" or "End" in
36 # its name should be mapped.
37 ATTRIBUTES_TO_MAP = {'paddingStart' : 'paddingLeft',
38 'drawableStart' : 'drawableLeft',
39 'layout_alignStart' : 'layout_alignLeft',
40 'layout_marginStart' : 'layout_marginLeft',
41 'layout_alignParentStart' : 'layout_alignParentLeft',
42 'layout_toStartOf' : 'layout_toLeftOf',
43 'paddingEnd' : 'paddingRight',
44 'drawableEnd' : 'drawableRight',
45 'layout_alignEnd' : 'layout_alignRight',
46 'layout_marginEnd' : 'layout_marginRight',
47 'layout_alignParentEnd' : 'layout_alignParentRight',
48 'layout_toEndOf' : 'layout_toRightOf'}
49
50 ATTRIBUTES_TO_MAP = dict(['android:' + k, 'android:' + v] for k, v
51 in ATTRIBUTES_TO_MAP.iteritems())
52
53 ATTRIBUTES_TO_MAP_REVERSED = dict([v,k] for k, v
54 in ATTRIBUTES_TO_MAP.iteritems())
55
56
57 def IterateXmlElements(node):
58 """minidom helper function that iterates all the element nodes.
59 Iteration order is pre-order depth-first."""
60 if node.nodeType == node.ELEMENT_NODE:
61 yield node
62 for child_node in node.childNodes:
63 for child_node_element in IterateXmlElements(child_node):
64 yield child_node_element
65
66
67 def WarnDeprecatedAttribute(name, value, filename):
68 if name in ATTRIBUTES_TO_MAP_REVERSED:
69 print >> sys.stderr, ('warning: ' + filename + ' should use ' +
70 ATTRIBUTES_TO_MAP_REVERSED[name] +
71 ' instead of ' + name)
72 elif name in GRAVITY_ATTRIBUTES and ('left' in value or 'right' in value):
73 print >> sys.stderr, ('warning: ' + filename +
74 ' should use start/end instead of left/right for ' +
75 name)
76
77
78 def GenerateV14StyleResource(input_filename, output_filename):
79 """Convert style resource to API 14 compatible style resource.
80
81 It's mostly a simple replacement, s/Start/Left s/End/Right,
82 on the attribute names specified by <item> element.
83 If input_filename does not contain style resources, do nothing.
84 """
85 dom = minidom.parse(input_filename)
86 style_elements = dom.getElementsByTagName('style')
87
88 if not style_elements:
89 return
90
91 for style_element in style_elements:
92 for item_element in style_element.getElementsByTagName('item'):
93 name = item_element.attributes['name'].value
94 value = item_element.childNodes[0].nodeValue
95 if name in ATTRIBUTES_TO_MAP:
96 item_element.attributes['name'].value = ATTRIBUTES_TO_MAP[name]
97 else:
98 WarnDeprecatedAttribute(name, value, input_filename)
99
100 build_utils.MakeDirectory(os.path.dirname(output_filename))
101 with open(output_filename, 'w') as f:
102 dom.writexml(f, '', ' ', '\n', encoding='utf-8')
103
104
105 def GenerateV14LayoutResource(input_filename, output_filename):
106 """Convert layout resource to API 14 compatible layout resource.
107
108 It's mostly a simple replacement, s/Start/Left s/End/Right,
109 on the attribute names.
110 """
111 dom = minidom.parse(input_filename)
112
113 # Iterate all the elements' attributes to find attributes to convert.
114 for element in IterateXmlElements(dom):
115 for name, value in list(element.attributes.items()):
116 # Convert any other API 17 Start/End attributes to Left/Right attributes.
117 # For example, from paddingStart="10dp" to paddingLeft="10dp"
118 # Note: gravity attributes are not necessary to convert because
119 # start/end values are backward-compatible. Explained at
120 # https://plus.sandbox.google.com/+RomanNurik/posts/huuJd8iVVXY?e=Showroom
121 if name in ATTRIBUTES_TO_MAP:
122 element.setAttribute(ATTRIBUTES_TO_MAP[name], value)
123 del element.attributes[name]
124 else:
125 WarnDeprecatedAttribute(name, value, input_filename)
126
127 build_utils.MakeDirectory(os.path.dirname(output_filename))
128 with open(output_filename, 'w') as f:
129 dom.writexml(f, '', ' ', '\n', encoding='utf-8')
130
131
132 def GenerateV14XmlResourcesInDir(input_dir, output_dir, only_styles=False):
133 """Convert resources to API 14 compatible XML resources in the directory."""
134 for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'):
135 output_filename = os.path.join(output_dir,
136 os.path.relpath(input_filename, input_dir))
137 if only_styles:
138 GenerateV14StyleResource(input_filename, output_filename)
139 else:
140 GenerateV14LayoutResource(input_filename, output_filename)
141
142
143 def ParseArgs():
144 """Parses command line options.
145
146 Returns:
147 An options object as from optparse.OptionsParser.parse_args()
148 """
149 parser = optparse.OptionParser()
150 parser.add_option('--res-dir',
151 help='directory containing resources '
152 'used to generate v14 resources')
153 parser.add_option('--res-v14-dir',
154 help='output directory into which '
155 'v14 resources will be generated')
156 parser.add_option('--stamp', help='File to touch on success')
157
158 options, args = parser.parse_args()
159
160 if args:
161 parser.error('No positional arguments should be given.')
162
163 # Check that required options have been provided.
164 required_options = ('res_dir', 'res_v14_dir')
165 build_utils.CheckOptions(options, parser, required=required_options)
166 return options
167
168
169 def main(argv):
170 options = ParseArgs()
171
172 build_utils.DeleteDirectory(options.res_v14_dir)
173 build_utils.MakeDirectory(options.res_v14_dir)
174
175 for name in os.listdir(options.res_dir):
176 if not os.path.isdir(os.path.join(options.res_dir, name)):
177 continue
178
179 dir_pieces = name.split('-')
180 resource_type = dir_pieces[0]
181 qualifiers = dir_pieces[1:]
182
183 # Android pre-v17 API doesn't support RTL. Skip.
184 if 'ldrtl' in qualifiers:
185 continue
186
187 input_dir = os.path.join(options.res_dir, name)
188 output_dir = os.path.join(options.res_v14_dir, name)
189
190 # We only convert resources under layout*/, xml*/,
191 # and style resources under values*/.
192 # TODO(kkimlabs): don't process xml directly once all layouts have
193 # been moved out of XML directory. see http://crbug.com/238458
194 if resource_type in ('layout', 'xml'):
195 GenerateV14XmlResourcesInDir(input_dir, output_dir)
196 elif resource_type in ('values'):
197 GenerateV14XmlResourcesInDir(input_dir, output_dir, only_styles=True)
198
199 if options.stamp:
200 build_utils.Touch(options.stamp)
201
202 if __name__ == '__main__':
203 sys.exit(main(sys.argv))
204
OLDNEW
« no previous file with comments | « build/android/gyp/generate_v14_compatible_resources.py ('k') | build/java.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698