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

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

Issue 1338393003: GN: Fix ChromePublic crash on launch from misconfigured resource overrides (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: line length Created 5 years, 3 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 | build/config/android/rules.gni » ('j') | 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 optparse 15 import optparse
15 import os 16 import os
16 import re 17 import re
17 import shutil 18 import shutil
18 import sys 19 import sys
19 20
20 import generate_v14_compatible_resources 21 import generate_v14_compatible_resources
21 22
22 from util import build_utils 23 from util import build_utils
23 24
24 # Import jinja2 from third_party/jinja2 25 # Import jinja2 from third_party/jinja2
25 sys.path.insert(1, 26 sys.path.insert(1,
26 os.path.join(os.path.dirname(__file__), '../../../third_party')) 27 os.path.join(os.path.dirname(__file__), '../../../third_party'))
27 from jinja2 import Template # pylint: disable=F0401 28 from jinja2 import Template # pylint: disable=F0401
28 29
29 30
31 # Represents a line from a R.txt file.
32 TextSymbolsEntry = collections.namedtuple('RTextEntry',
33 ('java_type', 'resource_type', 'name', 'value'))
34
35
30 def ParseArgs(args): 36 def ParseArgs(args):
31 """Parses command line options. 37 """Parses command line options.
32 38
33 Returns: 39 Returns:
34 An options object as from optparse.OptionsParser.parse_args() 40 An options object as from optparse.OptionsParser.parse_args()
35 """ 41 """
36 parser = optparse.OptionParser() 42 parser = optparse.OptionParser()
37 build_utils.AddDepfileOption(parser) 43 build_utils.AddDepfileOption(parser)
38 44
39 parser.add_option('--android-sdk', help='path to the Android SDK folder') 45 parser.add_option('--android-sdk', help='path to the Android SDK folder')
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 package_r_java_dir = os.path.join(r_dir, *package.split('.')) 134 package_r_java_dir = os.path.join(r_dir, *package.split('.'))
129 build_utils.MakeDirectory(package_r_java_dir) 135 build_utils.MakeDirectory(package_r_java_dir)
130 package_r_java_path = os.path.join(package_r_java_dir, 'R.java') 136 package_r_java_path = os.path.join(package_r_java_dir, 'R.java')
131 new_r_java = re.sub(r'package [.\w]*;', u'package %s;' % package, 137 new_r_java = re.sub(r'package [.\w]*;', u'package %s;' % package,
132 r_java_contents) 138 r_java_contents)
133 codecs.open(package_r_java_path, 'w', encoding='utf-8').write(new_r_java) 139 codecs.open(package_r_java_path, 'w', encoding='utf-8').write(new_r_java)
134 else: 140 else:
135 if len(extra_packages) != len(extra_r_text_files): 141 if len(extra_packages) != len(extra_r_text_files):
136 raise Exception('Need one R.txt file per extra package') 142 raise Exception('Need one R.txt file per extra package')
137 143
138 all_resources = {}
139 r_txt_file = os.path.join(r_dir, 'R.txt') 144 r_txt_file = os.path.join(r_dir, 'R.txt')
140 if not os.path.exists(r_txt_file): 145 if not os.path.exists(r_txt_file):
141 return 146 return
142 with open(r_txt_file) as f:
143 for line in f:
144 m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line)
145 if not m:
146 raise Exception('Unexpected line in R.txt: %s' % line)
147 java_type, resource_type, name, value = m.groups()
148 all_resources[(resource_type, name)] = (java_type, value)
149 147
148 # Map of (resource_type, name) -> Entry.
149 # Contains the correct values for resources.
150 all_resources = {}
151 for entry in _ParseTextSymbolsFile(r_txt_file):
152 all_resources[(entry.resource_type, entry.name)] = entry
153
154 # Map of package_name->resource_type->entry
155 resources_by_package = (
156 collections.defaultdict(lambda: collections.defaultdict(list)))
157 # Build the R.java files using each package's R.txt file, but replacing
158 # each entry's placeholder value with correct values from all_resources.
150 for package, r_text_file in zip(extra_packages, extra_r_text_files): 159 for package, r_text_file in zip(extra_packages, extra_r_text_files):
151 if os.path.exists(r_text_file): 160 if not os.path.exists(r_text_file):
152 package_r_java_dir = os.path.join(r_dir, *package.split('.')) 161 continue
153 build_utils.MakeDirectory(package_r_java_dir) 162 if package in resources_by_package:
154 package_r_java_path = os.path.join(package_r_java_dir, 'R.java') 163 raise Exception(('Package name "%s" appeared twice. All '
155 CreateExtraRJavaFile( 164 'android_resources() targets must use unique package '
156 package, package_r_java_path, r_text_file, all_resources, 165 'names, or no package name at all.') % package)
157 shared_resources) 166 resources_by_type = resources_by_package[package]
167 # The sub-R.txt files have the wrong values at this point. Read them to
168 # figure out which entries belong to them, but use the values from the
169 # main R.txt file.
170 for entry in _ParseTextSymbolsFile(r_text_file):
171 entry = all_resources[(entry.resource_type, entry.name)]
172 resources_by_type[entry.resource_type].append(entry)
173
174 for package, resources_by_type in resources_by_package.iteritems():
175 package_r_java_dir = os.path.join(r_dir, *package.split('.'))
176 build_utils.MakeDirectory(package_r_java_dir)
177 package_r_java_path = os.path.join(package_r_java_dir, 'R.java')
178 java_file_contents = _CreateExtraRJavaFile(
179 package, resources_by_type, shared_resources)
180 with open(package_r_java_path, 'w') as f:
181 f.write(java_file_contents)
158 182
159 183
160 def CreateExtraRJavaFile( 184 def _ParseTextSymbolsFile(path):
161 package, r_java_path, r_text_file, all_resources, shared_resources): 185 """Given an R.txt file, returns a list of TextSymbolsEntry."""
162 resources = {} 186 ret = []
163 with open(r_text_file) as f: 187 with open(path) as f:
164 for line in f: 188 for line in f:
165 m = re.match(r'int(?:\[\])? (\w+) (\w+) ', line) 189 m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line)
166 if not m: 190 if not m:
167 raise Exception('Unexpected line in R.txt: %s' % line) 191 raise Exception('Unexpected line in R.txt: %s' % line)
168 resource_type, name = m.groups() 192 java_type, resource_type, name, value = m.groups()
169 java_type, value = all_resources[(resource_type, name)] 193 ret.append(TextSymbolsEntry(java_type, resource_type, name, value))
170 if resource_type not in resources: 194 return ret
171 resources[resource_type] = []
172 resources[resource_type].append((name, java_type, value))
173 195
196
197 def _CreateExtraRJavaFile(package, resources_by_type, shared_resources):
198 """Generates the contents of a R.java file."""
174 template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */ 199 template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */
175 200
176 package {{ package }}; 201 package {{ package }};
177 202
178 public final class R { 203 public final class R {
179 {% for resource_type in resources %} 204 {% for resource_type in resources %}
180 public static final class {{ resource_type }} { 205 public static final class {{ resource_type }} {
181 {% for name, java_type, value in resources[resource_type] %} 206 {% for e in resources[resource_type] %}
182 {% if shared_resources %} 207 {% if shared_resources %}
183 public static {{ java_type }} {{ name }} = {{ value }}; 208 public static {{ e.java_type }} {{ e.name }} = {{ e.value }};
184 {% else %} 209 {% else %}
185 public static final {{ java_type }} {{ name }} = {{ value }}; 210 public static final {{ e.java_type }} {{ e.name }} = {{ e.value }};
186 {% endif %} 211 {% endif %}
187 {% endfor %} 212 {% endfor %}
188 } 213 }
189 {% endfor %} 214 {% endfor %}
190 {% if shared_resources %} 215 {% if shared_resources %}
191 public static void onResourcesLoaded(int packageId) { 216 public static void onResourcesLoaded(int packageId) {
192 {% for resource_type in resources %} 217 {% for resource_type in resources %}
193 {% for name, java_type, value in resources[resource_type] %} 218 {% for e in resources[resource_type] %}
194 {% if java_type == 'int[]' %} 219 {% if e.java_type == 'int[]' %}
195 for(int i = 0; i < {{ resource_type }}.{{ name }}.length; ++i) { 220 for(int i = 0; i < {{ e.resource_type }}.{{ e.name }}.length; ++i) {
196 {{ resource_type }}.{{ name }}[i] = 221 {{ e.resource_type }}.{{ e.name }}[i] =
197 ({{ resource_type }}.{{ name }}[i] & 0x00ffffff) 222 ({{ e.resource_type }}.{{ e.name }}[i] & 0x00ffffff)
198 | (packageId << 24); 223 | (packageId << 24);
199 } 224 }
200 {% else %} 225 {% else %}
201 {{ resource_type }}.{{ name }} = 226 {{ e.resource_type }}.{{ e.name }} =
202 ({{ resource_type }}.{{ name }} & 0x00ffffff) 227 ({{ e.resource_type }}.{{ e.name }} & 0x00ffffff)
203 | (packageId << 24); 228 | (packageId << 24);
204 {% endif %} 229 {% endif %}
205 {% endfor %} 230 {% endfor %}
206 {% endfor %} 231 {% endfor %}
207 } 232 }
208 {% endif %} 233 {% endif %}
209 } 234 }
210 """, trim_blocks=True, lstrip_blocks=True) 235 """, trim_blocks=True, lstrip_blocks=True)
211 236
212 output = template.render(package=package, resources=resources, 237 return template.render(package=package, resources=resources_by_type,
213 shared_resources=shared_resources) 238 shared_resources=shared_resources)
214 with open(r_java_path, 'w') as f:
215 f.write(output)
216 239
217 240
218 def CrunchDirectory(aapt, input_dir, output_dir): 241 def CrunchDirectory(aapt, input_dir, output_dir):
219 """Crunches the images in input_dir and its subdirectories into output_dir. 242 """Crunches the images in input_dir and its subdirectories into output_dir.
220 243
221 If an image is already optimized, crunching often increases image size. In 244 If an image is already optimized, crunching often increases image size. In
222 this case, the crunched image is overwritten with the original image. 245 this case, the crunched image is overwritten with the original image.
223 """ 246 """
224 aapt_cmd = [aapt, 247 aapt_cmd = [aapt,
225 'crunch', 248 'crunch',
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 if options.depfile: 432 if options.depfile:
410 input_files += build_utils.GetPythonDependencies() 433 input_files += build_utils.GetPythonDependencies()
411 build_utils.WriteDepfile(options.depfile, input_files) 434 build_utils.WriteDepfile(options.depfile, input_files)
412 435
413 if options.stamp: 436 if options.stamp:
414 build_utils.Touch(options.stamp) 437 build_utils.Touch(options.stamp)
415 438
416 439
417 if __name__ == '__main__': 440 if __name__ == '__main__':
418 main() 441 main()
OLDNEW
« no previous file with comments | « no previous file | build/config/android/rules.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698