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

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

Issue 2572253002: DO NOT SUBMIT shrink R.java files via inheritance (Closed)
Patch Set: not using org.chromium package prefix Created 3 years, 11 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2012 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 """Process Android resources to generate R.java, and prepare for packaging. 7 """Process Android resources to generate R.java, and prepare for packaging.
8 8
9 This will crunch images and generate v14 compatible resources 9 This will crunch images and generate v14 compatible resources
10 (see generate_v14_compatible_resources.py). 10 (see generate_v14_compatible_resources.py).
11 """ 11 """
12 12
13 import codecs 13 import codecs
14 import collections 14 import collections
15 import optparse 15 import optparse
16 import os 16 import os
17 import re 17 import re
18 import shutil 18 import shutil
19 import sys 19 import sys
20 import xml.etree.ElementTree 20 import xml.etree.ElementTree
21 21
22 import generate_v14_compatible_resources 22 import generate_v14_compatible_resources
23 23
24 from util import build_utils 24 from util import build_utils
25 25
26 _ROOT_R_JAVA_PACKAGE_PREFIX = 'gen'
27
28
26 # Import jinja2 from third_party/jinja2 29 # Import jinja2 from third_party/jinja2
27 sys.path.insert(1, 30 sys.path.insert(1,
28 os.path.join(os.path.dirname(__file__), '../../../third_party')) 31 os.path.join(os.path.dirname(__file__), '../../../third_party'))
29 from jinja2 import Template # pylint: disable=F0401 32 from jinja2 import Template # pylint: disable=F0401
30 33
31 34
32 # Represents a line from a R.txt file. 35 # Represents a line from a R.txt file.
33 TextSymbolsEntry = collections.namedtuple('RTextEntry', 36 TextSymbolsEntry = collections.namedtuple('RTextEntry',
34 ('java_type', 'resource_type', 'name', 'value')) 37 ('java_type', 'resource_type', 'name', 'value'))
35 38
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 if options.extra_r_text_files: 145 if options.extra_r_text_files:
143 options.extra_r_text_files = ( 146 options.extra_r_text_files = (
144 build_utils.ParseGnList(options.extra_r_text_files)) 147 build_utils.ParseGnList(options.extra_r_text_files))
145 else: 148 else:
146 options.extra_r_text_files = [] 149 options.extra_r_text_files = []
147 150
148 return options 151 return options
149 152
150 153
151 def CreateRJavaFiles(srcjar_dir, main_r_txt_file, packages, r_txt_files, 154 def CreateRJavaFiles(srcjar_dir, main_r_txt_file, packages, r_txt_files,
152 shared_resources): 155 shared_resources, srcjar_name):
153 assert len(packages) == len(r_txt_files), 'Need one R.txt file per package' 156 assert len(packages) == len(r_txt_files), 'Need one R.txt file per package'
154 157
155 # Map of (resource_type, name) -> Entry. 158 # Map of (resource_type, name) -> Entry.
156 # Contains the correct values for resources. 159 # Contains the correct values for resources.
157 all_resources = {} 160 all_resources = {}
161 all_resources_by_type = collections.defaultdict(list)
158 for entry in _ParseTextSymbolsFile(main_r_txt_file): 162 for entry in _ParseTextSymbolsFile(main_r_txt_file):
159 all_resources[(entry.resource_type, entry.name)] = entry 163 all_resources[(entry.resource_type, entry.name)] = entry
164 all_resources_by_type[entry.resource_type].append(entry)
165
166 # Write Root R.java.
167 root_r_java_package = _ROOT_R_JAVA_PACKAGE_PREFIX + '.' + srcjar_name
168 root_r_java_dir = os.path.join(srcjar_dir, *root_r_java_package.split('.'))
169 build_utils.MakeDirectory(root_r_java_dir)
170 root_r_java_path = os.path.join(root_r_java_dir, 'R.java')
171 root_java_file_contents = _CreateRootRJavaFile(
172 root_r_java_package, all_resources_by_type, shared_resources)
173 with open(root_r_java_path, 'w') as f:
174 f.write(root_java_file_contents)
160 175
161 # Map of package_name->resource_type->entry 176 # Map of package_name->resource_type->entry
162 resources_by_package = ( 177 resources_by_package = (
163 collections.defaultdict(lambda: collections.defaultdict(list))) 178 collections.defaultdict(lambda: collections.defaultdict(list)))
164 # Build the R.java files using each package's R.txt file, but replacing 179 # Build the R.java files using each package's R.txt file, but replacing
165 # each entry's placeholder value with correct values from all_resources. 180 # each entry's placeholder value with correct values from all_resources.
166 for package, r_txt_file in zip(packages, r_txt_files): 181 for package, r_txt_file in zip(packages, r_txt_files):
167 if package in resources_by_package: 182 if package in resources_by_package:
168 raise Exception(('Package name "%s" appeared twice. All ' 183 raise Exception(('Package name "%s" appeared twice. All '
169 'android_resources() targets must use unique package ' 184 'android_resources() targets must use unique package '
(...skipping 20 matching lines...) Expand all
190 # correctly by running Proguard on the APK: it will report missing 205 # correctly by running Proguard on the APK: it will report missing
191 # fields. 206 # fields.
192 if entry: 207 if entry:
193 resources_by_type[entry.resource_type].append(entry) 208 resources_by_type[entry.resource_type].append(entry)
194 209
195 for package, resources_by_type in resources_by_package.iteritems(): 210 for package, resources_by_type in resources_by_package.iteritems():
196 package_r_java_dir = os.path.join(srcjar_dir, *package.split('.')) 211 package_r_java_dir = os.path.join(srcjar_dir, *package.split('.'))
197 build_utils.MakeDirectory(package_r_java_dir) 212 build_utils.MakeDirectory(package_r_java_dir)
198 package_r_java_path = os.path.join(package_r_java_dir, 'R.java') 213 package_r_java_path = os.path.join(package_r_java_dir, 'R.java')
199 java_file_contents = _CreateRJavaFile( 214 java_file_contents = _CreateRJavaFile(
200 package, resources_by_type, shared_resources) 215 package, root_r_java_package, resources_by_type, shared_resources)
201 with open(package_r_java_path, 'w') as f: 216 with open(package_r_java_path, 'w') as f:
202 f.write(java_file_contents) 217 f.write(java_file_contents)
203 218
204 219
205 def _ParseTextSymbolsFile(path): 220 def _ParseTextSymbolsFile(path):
206 """Given an R.txt file, returns a list of TextSymbolsEntry.""" 221 """Given an R.txt file, returns a list of TextSymbolsEntry."""
207 ret = [] 222 ret = []
208 with open(path) as f: 223 with open(path) as f:
209 for line in f: 224 for line in f:
210 m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line) 225 m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line)
211 if not m: 226 if not m:
212 raise Exception('Unexpected line in R.txt: %s' % line) 227 raise Exception('Unexpected line in R.txt: %s' % line)
213 java_type, resource_type, name, value = m.groups() 228 java_type, resource_type, name, value = m.groups()
214 ret.append(TextSymbolsEntry(java_type, resource_type, name, value)) 229 ret.append(TextSymbolsEntry(java_type, resource_type, name, value))
215 return ret 230 return ret
216 231
217 232
218 def _CreateRJavaFile(package, resources_by_type, shared_resources): 233 def _CreateRJavaFile(
234 package, root_r_java_package, resources_by_type, shared_resources):
235 # TODO fix comments
236 """Generates the contents of a R.java file."""
237 template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */
238
239 package {{ package }};
240
241 public final class R {
242 {% for resource_type in resource_types %}
243 public static final class {{ resource_type }} extends
244 {{ root_package }}.R.{{ resource_type }} {}
245 {% endfor %}
246 {% if shared_resources %}
247 public static void onResourcesLoaded(int packageId) {
248 {{ root_package }}.R.onResourcesLoaded(packageId);
249 }
250 {% endif %}
251 }
252 """, trim_blocks=True, lstrip_blocks=True)
253
254 return template.render(package=package,
255 resources=resources_by_type,
256 resource_types=sorted(resources_by_type),
257 root_package=root_r_java_package,
258 shared_resources=shared_resources)
259
260
261 def _CreateRootRJavaFile(package, all_resources_by_type, shared_resources):
262 # TODO fix comments
219 """Generates the contents of a R.java file.""" 263 """Generates the contents of a R.java file."""
220 # Keep these assignments all on one line to make diffing against regular 264 # Keep these assignments all on one line to make diffing against regular
221 # aapt-generated files easier. 265 # aapt-generated files easier.
222 create_id = ('{{ e.resource_type }}.{{ e.name }} ^= packageIdTransform;') 266 create_id = ('{{ e.resource_type }}.{{ e.name }} ^= packageIdTransform;')
223 create_id_arr = ('{{ e.resource_type }}.{{ e.name }}[i] ^=' 267 create_id_arr = ('{{ e.resource_type }}.{{ e.name }}[i] ^='
224 ' packageIdTransform;') 268 ' packageIdTransform;')
225 # Here we diverge from what aapt does. Because we have so many 269 # Here we diverge from what aapt does. Because we have so many
226 # resources, the onResourcesLoaded method was exceeding the 64KB limit that 270 # resources, the onResourcesLoaded method was exceeding the 64KB limit that
227 # Java imposes. For this reason we split onResourcesLoaded into different 271 # Java imposes. For this reason we split onResourcesLoaded into different
228 # methods for each resource type. 272 # methods for each resource type.
229 template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */ 273 template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */
230 274
231 package {{ package }}; 275 package {{ package }};
232 276
233 public final class R { 277 public final class R {
234 private static boolean sResourcesDidLoad; 278 private static boolean sResourcesDidLoad;
235 {% for resource_type in resource_types %} 279 {% for resource_type in resource_types %}
236 public static final class {{ resource_type }} { 280 public static class {{ resource_type }} {
237 {% for e in resources[resource_type] %} 281 {% for e in resources[resource_type] %}
238 {% if shared_resources %} 282 {% if shared_resources %}
239 public static {{ e.java_type }} {{ e.name }} = {{ e.value }}; 283 public static {{ e.java_type }} {{ e.name }} = {{ e.value }};
240 {% else %} 284 {% else %}
241 public static final {{ e.java_type }} {{ e.name }} = {{ e.value }}; 285 public static final {{ e.java_type }} {{ e.name }} = {{ e.value }};
242 {% endif %} 286 {% endif %}
243 {% endfor %} 287 {% endfor %}
244 } 288 }
245 {% endfor %} 289 {% endfor %}
246 {% if shared_resources %} 290 {% if shared_resources %}
247 public static void onResourcesLoaded(int packageId) { 291 public static void onResourcesLoaded(int packageId) {
248 assert !sResourcesDidLoad; 292 if (sResourcesDidLoad) {
293 return;
294 }
249 sResourcesDidLoad = true; 295 sResourcesDidLoad = true;
250 int packageIdTransform = (packageId ^ 0x7f) << 24; 296 int packageIdTransform = (packageId ^ 0x7f) << 24;
251 {% for resource_type in resource_types %} 297 {% for resource_type in resource_types %}
252 onResourcesLoaded{{ resource_type|title }}(packageIdTransform); 298 onResourcesLoaded{{ resource_type|title }}(packageIdTransform);
253 {% for e in resources[resource_type] %} 299 {% for e in resources[resource_type] %}
254 {% if e.java_type == 'int[]' %} 300 {% if e.java_type == 'int[]' %}
255 for(int i = 0; i < {{ e.resource_type }}.{{ e.name }}.length; ++i) { 301 for(int i = 0; i < {{ e.resource_type }}.{{ e.name }}.length; ++i) {
256 """ + create_id_arr + """ 302 """ + create_id_arr + """
257 } 303 }
258 {% endif %} 304 {% endif %}
259 {% endfor %} 305 {% endfor %}
260 {% endfor %} 306 {% endfor %}
261 } 307 }
262 {% for res_type in resource_types %} 308 {% for res_type in resource_types %}
263 private static void onResourcesLoaded{{ res_type|title }} ( 309 private static void onResourcesLoaded{{ res_type|title }} (
264 int packageIdTransform) { 310 int packageIdTransform) {
265 {% for e in resources[res_type] %} 311 {% for e in resources[res_type] %}
266 {% if res_type != 'styleable' and e.java_type != 'int[]' %} 312 {% if res_type != 'styleable' and e.java_type != 'int[]' %}
267 """ + create_id + """ 313 """ + create_id + """
268 {% endif %} 314 {% endif %}
269 {% endfor %} 315 {% endfor %}
270 } 316 }
271 {% endfor %} 317 {% endfor %}
272 {% endif %} 318 {% endif %}
273 } 319 }
274 """, trim_blocks=True, lstrip_blocks=True) 320 """, trim_blocks=True, lstrip_blocks=True)
275 321
276 return template.render(package=package, 322 return template.render(package=package,
277 resources=resources_by_type, 323 resources=all_resources_by_type,
278 resource_types=sorted(resources_by_type), 324 resource_types=sorted(all_resources_by_type),
279 shared_resources=shared_resources) 325 shared_resources=shared_resources)
280 326
281 327
282 def CrunchDirectory(aapt, input_dir, output_dir): 328 def CrunchDirectory(aapt, input_dir, output_dir):
283 """Crunches the images in input_dir and its subdirectories into output_dir. 329 """Crunches the images in input_dir and its subdirectories into output_dir.
284 330
285 If an image is already optimized, crunching often increases image size. In 331 If an image is already optimized, crunching often increases image size. In
286 this case, the crunched image is overwritten with the original image. 332 this case, the crunched image is overwritten with the original image.
287 """ 333 """
288 aapt_cmd = [aapt, 334 aapt_cmd = [aapt,
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 # - there was already a dependent android_resources() with the same 518 # - there was already a dependent android_resources() with the same
473 # package (occurs mostly when an apk target and resources target share 519 # package (occurs mostly when an apk target and resources target share
474 # an AndroidManifest.xml) 520 # an AndroidManifest.xml)
475 if cur_package != 'dummy.package' and cur_package not in packages: 521 if cur_package != 'dummy.package' and cur_package not in packages:
476 packages.append(cur_package) 522 packages.append(cur_package)
477 r_txt_files.append(r_txt_path) 523 r_txt_files.append(r_txt_path)
478 524
479 if packages: 525 if packages:
480 shared_resources = options.shared_resources or options.app_as_shared_lib 526 shared_resources = options.shared_resources or options.app_as_shared_lib
481 CreateRJavaFiles(srcjar_dir, r_txt_path, packages, r_txt_files, 527 CreateRJavaFiles(srcjar_dir, r_txt_path, packages, r_txt_files,
482 shared_resources) 528 shared_resources, os.path.basename(options.srcjar_out))
483 529
484 # This is the list of directories with resources to put in the final .zip 530 # This is the list of directories with resources to put in the final .zip
485 # file. The order of these is important so that crunched/v14 resources 531 # file. The order of these is important so that crunched/v14 resources
486 # override the normal ones. 532 # override the normal ones.
487 zip_resource_dirs = input_resource_dirs + [v14_dir] 533 zip_resource_dirs = input_resource_dirs + [v14_dir]
488 534
489 base_crunch_dir = os.path.join(temp_dir, 'crunch') 535 base_crunch_dir = os.path.join(temp_dir, 'crunch')
490 536
491 # Crunch image resources. This shrinks png files and is necessary for 537 # Crunch image resources. This shrinks png files and is necessary for
492 # 9-patch images to display correctly. 'aapt crunch' accepts only a single 538 # 9-patch images to display correctly. 'aapt crunch' accepts only a single
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 options, 606 options,
561 input_paths=input_paths, 607 input_paths=input_paths,
562 input_strings=input_strings, 608 input_strings=input_strings,
563 output_paths=output_paths, 609 output_paths=output_paths,
564 # TODO(agrieve): Remove R_dir when it's no longer used (used only by GYP). 610 # TODO(agrieve): Remove R_dir when it's no longer used (used only by GYP).
565 force=options.R_dir) 611 force=options.R_dir)
566 612
567 613
568 if __name__ == '__main__': 614 if __name__ == '__main__':
569 main(sys.argv[1:]) 615 main(sys.argv[1:])
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698