Chromium Code Reviews| Index: build/android/gyp/process_resources.py | 
| diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py | 
| index 4e6c27dcb8fb71dba499d33e2ee5962460fd0bce..503266a2c3ed01680b54c02a3d1b2c19492b3a15 100755 | 
| --- a/build/android/gyp/process_resources.py | 
| +++ b/build/android/gyp/process_resources.py | 
| @@ -10,7 +10,6 @@ This will crunch images and generate v14 compatible resources | 
| (see generate_v14_compatible_resources.py). | 
| """ | 
| -import codecs | 
| import optparse | 
| import os | 
| import re | 
| @@ -22,6 +21,10 @@ import generate_v14_compatible_resources | 
| from util import build_utils | 
| +# Import jinja2 from third_party/jinja2 | 
| +sys.path.append(os.path.join(os.path.dirname(__file__), '../../../third_party')) | 
| +from jinja2 import Template # pylint: disable=F0401 | 
| + | 
| def ParseArgs(args): | 
| """Parses command line options. | 
| @@ -57,6 +60,8 @@ def ParseArgs(args): | 
| help='directory to hold generated R.java.') | 
| parser.add_option('--srcjar-out', | 
| help='Path to srcjar to contain generated R.java.') | 
| + parser.add_option('--r-text-out', | 
| + help='Path to store the R.txt file generated by appt.') | 
| parser.add_option('--proguard-file', | 
| help='Path to proguard.txt generated file') | 
| @@ -71,8 +76,6 @@ def ParseArgs(args): | 
| parser.add_option( | 
| '--extra-res-packages', | 
| help='Additional package names to generate R.java files for') | 
| - # TODO(cjhopman): Actually use --extra-r-text-files. We currently include all | 
| - # the resources in all R.java files for a particular apk. | 
| parser.add_option( | 
| '--extra-r-text-files', | 
| help='For each additional package, the R.txt file should contain a ' | 
| @@ -108,24 +111,89 @@ def ParseArgs(args): | 
| return options | 
| -def CreateExtraRJavaFiles(r_dir, extra_packages): | 
| - java_files = build_utils.FindInDirectory(r_dir, "R.java") | 
| - if len(java_files) != 1: | 
| +def CreateExtraRJavaFiles( | 
| + r_dir, extra_packages, extra_r_text_files, shared_resources): | 
| + if len(extra_packages) != len(extra_r_text_files): | 
| + raise Exception('Need one R.txt file per extra package') | 
| + | 
| + all_resources = {} | 
| + r_txt_file = os.path.join(r_dir, 'R.txt') | 
| + if not os.path.exists(r_txt_file): | 
| return | 
| - r_java_file = java_files[0] | 
| - r_java_contents = codecs.open(r_java_file, encoding='utf-8').read() | 
| - | 
| - for package in extra_packages: | 
| - package_r_java_dir = os.path.join(r_dir, *package.split('.')) | 
| - build_utils.MakeDirectory(package_r_java_dir) | 
| - package_r_java_path = os.path.join(package_r_java_dir, 'R.java') | 
| - new_r_java = re.sub(r'package [.\w]*;', u'package %s;' % package, | 
| - r_java_contents) | 
| - codecs.open(package_r_java_path, 'w', encoding='utf-8').write(new_r_java) | 
| - # TODO(cjhopman): These extra package's R.java files should be filtered to | 
| - # only contain the resources listed in their R.txt files. At this point, we | 
| - # have already compiled those other libraries, so doing this would only | 
| - # affect how the code in this .apk target could refer to the resources. | 
| + with open(r_txt_file) as f: | 
| + for line in f: | 
| + m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line) | 
| + if not m: | 
| + raise Exception('Unexpected line in R.txt: %s' % line) | 
| + java_type, resource_type, name, value = m.groups() | 
| + all_resources[(resource_type, name)] = (java_type, value) | 
| + | 
| + for package, r_text_file in zip(extra_packages, extra_r_text_files): | 
| + if os.path.exists(r_text_file): | 
| + package_r_java_dir = os.path.join(r_dir, *package.split('.')) | 
| + build_utils.MakeDirectory(package_r_java_dir) | 
| + package_r_java_path = os.path.join(package_r_java_dir, 'R.java') | 
| + CreateExtraRJavaFile( | 
| + package, package_r_java_path, r_text_file, all_resources, | 
| + shared_resources) | 
| + | 
| + | 
| +def CreateExtraRJavaFile( | 
| + package, r_java_path, r_text_file, all_resources, shared_resources): | 
| + resources = {} | 
| + with open(r_text_file) as f: | 
| + for line in f: | 
| + m = re.match(r'int(?:\[\])? (\w+) (\w+) ', line) | 
| + if not m: | 
| + raise Exception('Unexpected line in R.txt: %s' % line) | 
| + resource_type, name = m.groups() | 
| + java_type, value = all_resources[(resource_type, name)] | 
| + if resource_type not in resources: | 
| + resources[resource_type] = [] | 
| + resources[resource_type].append((name, java_type, value)) | 
| + | 
| + template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */ | 
| + | 
| +package {{ package }}; | 
| + | 
| +public final class R { | 
| + {% for resource_type in resources %} | 
| + public static final class {{ resource_type }} { | 
| + {% for name, java_type, value in resources[resource_type] %} | 
| + {% if shared_resources %} | 
| + public static {{ java_type }} {{ name }} = {{ value }}; | 
| + {% else %} | 
| + public static final {{ java_type }} {{ name }} = {{ value }}; | 
| + {% endif %} | 
| + {% endfor %} | 
| + } | 
| + {% endfor %} | 
| + {% if shared_resources %} | 
| + public static void onResourcesLoaded(int packageId) { | 
| + {% for resource_type in resources %} | 
| + {% for name, java_type, value in resources[resource_type] %} | 
| + {% if java_type == 'int[]' %} | 
| + for(int i = 0; i < {{ resource_type }}.{{ name }}.length; ++i) { | 
| + {{ resource_type }}.{{ name }}[i] = | 
| + ({{ resource_type }}.{{ name }}[i] & 0x00ffffff) | 
| + | (packageId << 24); | 
| + } | 
| + {% else %} | 
| + {{ resource_type }}.{{ name }} = | 
| + ({{ resource_type }}.{{ name }} & 0x00ffffff) | 
| + | (packageId << 24); | 
| + {% endif %} | 
| + {% endfor %} | 
| + {% endfor %} | 
| + } | 
| + {% endif %} | 
| +} | 
| +""", trim_blocks=True, lstrip_blocks=True) | 
| + | 
| + output = template.render(package=package, resources=resources, | 
| + shared_resources=shared_resources) | 
| + with open(r_java_path, 'w') as f: | 
| + f.write(output) | 
| def CrunchDirectory(aapt, input_dir, output_dir): | 
| @@ -280,7 +348,9 @@ def main(): | 
| if options.extra_res_packages: | 
| CreateExtraRJavaFiles( | 
| gen_dir, | 
| - build_utils.ParseGypList(options.extra_res_packages)) | 
| + build_utils.ParseGypList(options.extra_res_packages), | 
| + build_utils.ParseGypList(options.extra_r_text_files), | 
| + options.shared_resources) | 
| # This is the list of directories with resources to put in the final .zip | 
| # file. The order of these is important so that crunched/v14 resources | 
| @@ -310,6 +380,10 @@ def main(): | 
| else: | 
| build_utils.ZipDir(options.srcjar_out, gen_dir) | 
| + if options.r_text_out: | 
| + r_text_path = os.path.join(gen_dir, 'R.txt') | 
| 
 
cjhopman
2015/05/06 22:31:44
This needs to handle the case when aapt doesn't ge
 
 | 
| + shutil.copyfile(r_text_path, options.r_text_out) | 
| + | 
| if options.depfile: | 
| input_files += build_utils.GetPythonDependencies() | 
| build_utils.WriteDepfile(options.depfile, input_files) |