OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2014 The Chromium Authors. All rights reserved. | 3 # Copyright 2014 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 # pylint: disable=C0301 | 7 # pylint: disable=C0301 |
8 """Package resources into an apk. | 8 """Package resources into an apk. |
9 | 9 |
10 See https://android.googlesource.com/platform/tools/base/+/master/legacy/ant-tas
ks/src/main/java/com/android/ant/AaptExecTask.java | 10 See https://android.googlesource.com/platform/tools/base/+/master/legacy/ant-tas
ks/src/main/java/com/android/ant/AaptExecTask.java |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 action='store_true', | 128 action='store_true', |
129 help='Enables density splits') | 129 help='Enables density splits') |
130 parser.add_option('--language-splits', | 130 parser.add_option('--language-splits', |
131 default='[]', | 131 default='[]', |
132 help='GN list of languages to create splits for') | 132 help='GN list of languages to create splits for') |
133 parser.add_option('--locale-whitelist', | 133 parser.add_option('--locale-whitelist', |
134 default='[]', | 134 default='[]', |
135 help='GN list of languages to include. All other language ' | 135 help='GN list of languages to include. All other language ' |
136 'configs will be stripped out. List may include ' | 136 'configs will be stripped out. List may include ' |
137 'a combination of Android locales or Chrome locales.') | 137 'a combination of Android locales or Chrome locales.') |
138 | |
139 parser.add_option('--apk-path', | 138 parser.add_option('--apk-path', |
140 help='Path to output (partial) apk.') | 139 help='Path to output (partial) apk.') |
| 140 parser.add_option('--exclude-xxxhdpi', action='store_true', |
| 141 help='Do not include xxxhdpi drawables.') |
| 142 parser.add_option('--xxxhdpi-whitelist', |
| 143 default='[]', |
| 144 help='GN list of globs that say which xxxhdpi images to ' |
| 145 'include even when --exclude-xxxhdpi is set.') |
141 | 146 |
142 options, positional_args = parser.parse_args(args) | 147 options, positional_args = parser.parse_args(args) |
143 | 148 |
144 if positional_args: | 149 if positional_args: |
145 parser.error('No positional arguments should be given.') | 150 parser.error('No positional arguments should be given.') |
146 | 151 |
147 # Check that required options have been provided. | 152 # Check that required options have been provided. |
148 required_options = ('android_sdk_jar', 'aapt_path', 'configuration_name', | 153 required_options = ('android_sdk_jar', 'aapt_path', 'configuration_name', |
149 'android_manifest', 'version_code', 'version_name', | 154 'android_manifest', 'version_code', 'version_name', |
150 'apk_path') | 155 'apk_path') |
151 | 156 |
152 build_utils.CheckOptions(options, parser, required=required_options) | 157 build_utils.CheckOptions(options, parser, required=required_options) |
153 | 158 |
154 options.resource_zips = build_utils.ParseGnList(options.resource_zips) | 159 options.resource_zips = build_utils.ParseGnList(options.resource_zips) |
155 options.language_splits = build_utils.ParseGnList(options.language_splits) | 160 options.language_splits = build_utils.ParseGnList(options.language_splits) |
156 options.locale_whitelist = build_utils.ParseGnList(options.locale_whitelist) | 161 options.locale_whitelist = build_utils.ParseGnList(options.locale_whitelist) |
| 162 options.xxxhdpi_whitelist = build_utils.ParseGnList(options.xxxhdpi_whitelist) |
157 return options | 163 return options |
158 | 164 |
159 | 165 |
160 def _ToAaptLocales(locale_whitelist): | 166 def _ToAaptLocales(locale_whitelist): |
161 """Converts the list of Chrome locales to aapt config locales.""" | 167 """Converts the list of Chrome locales to aapt config locales.""" |
162 ret = set() | 168 ret = set() |
163 for locale in locale_whitelist: | 169 for locale in locale_whitelist: |
164 locale = _CHROME_TO_ANDROID_LOCALE_MAP.get(locale, locale) | 170 locale = _CHROME_TO_ANDROID_LOCALE_MAP.get(locale, locale) |
165 if locale is None or ('-' in locale and '-r' not in locale): | 171 if locale is None or ('-' in locale and '-r' not in locale): |
166 raise Exception('_CHROME_TO_ANDROID_LOCALE_MAP needs updating.' | 172 raise Exception('_CHROME_TO_ANDROID_LOCALE_MAP needs updating.' |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 | 207 |
202 def PackageArgsForExtractedZip(d): | 208 def PackageArgsForExtractedZip(d): |
203 """Returns the aapt args for an extracted resources zip. | 209 """Returns the aapt args for an extracted resources zip. |
204 | 210 |
205 A resources zip either contains the resources for a single target or for | 211 A resources zip either contains the resources for a single target or for |
206 multiple targets. If it is multiple targets merged into one, the actual | 212 multiple targets. If it is multiple targets merged into one, the actual |
207 resource directories will be contained in the subdirectories 0, 1, 2, ... | 213 resource directories will be contained in the subdirectories 0, 1, 2, ... |
208 """ | 214 """ |
209 subdirs = [os.path.join(d, s) for s in os.listdir(d)] | 215 subdirs = [os.path.join(d, s) for s in os.listdir(d)] |
210 subdirs = [s for s in subdirs if os.path.isdir(s)] | 216 subdirs = [s for s in subdirs if os.path.isdir(s)] |
211 is_multi = '0' in [os.path.basename(s) for s in subdirs] | 217 is_multi = any(os.path.basename(s).isdigit() for s in subdirs) |
212 if is_multi: | 218 if is_multi: |
213 res_dirs = sorted(subdirs, key=lambda p : int(os.path.basename(p))) | 219 res_dirs = sorted(subdirs, key=lambda p : int(os.path.basename(p))) |
214 else: | 220 else: |
215 res_dirs = [d] | 221 res_dirs = [d] |
216 package_command = [] | 222 package_command = [] |
217 for d in res_dirs: | 223 for d in res_dirs: |
218 MoveImagesToNonMdpiFolders(d) | 224 MoveImagesToNonMdpiFolders(d) |
219 package_command += ['-S', d] | 225 package_command += ['-S', d] |
220 return package_command | 226 return package_command |
221 | 227 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 if 'Debug' in options.configuration_name: | 301 if 'Debug' in options.configuration_name: |
296 package_command += ['--debug-mode'] | 302 package_command += ['--debug-mode'] |
297 | 303 |
298 if options.locale_whitelist: | 304 if options.locale_whitelist: |
299 aapt_locales = _ToAaptLocales(options.locale_whitelist) | 305 aapt_locales = _ToAaptLocales(options.locale_whitelist) |
300 package_command += ['-c', ','.join(aapt_locales)] | 306 package_command += ['-c', ','.join(aapt_locales)] |
301 | 307 |
302 return package_command | 308 return package_command |
303 | 309 |
304 | 310 |
| 311 def _ResourceNameFromPath(path): |
| 312 return os.path.splitext(os.path.basename(path))[0] |
| 313 |
| 314 |
| 315 def _CreateExtractPredicate(dep_zips, exclude_xxxhdpi, xxxhdpi_whitelist): |
| 316 if not exclude_xxxhdpi: |
| 317 # Do not extract dotfiles (e.g. ".gitkeep"). aapt ignores them anyways. |
| 318 return lambda path: os.path.basename(path)[0] != '.' |
| 319 |
| 320 # Returns False only for xxxhdpi non-mipmap, non-whitelisted drawables. |
| 321 naive_predicate = lambda path: ( |
| 322 not re.search(r'[/-]xxxhdpi[/-]', path) or |
| 323 re.search(r'[/-]mipmap[/-]', path) or |
| 324 build_utils.MatchesGlob(path, xxxhdpi_whitelist)) |
| 325 |
| 326 # Build a set of all non-xxxhdpi drawables to ensure that we never exclude any |
| 327 # xxxhdpi drawable that does not exist in other densities. |
| 328 non_xxxhdpi_drawables = set() |
| 329 for resource_zip_path in dep_zips: |
| 330 with zipfile.ZipFile(resource_zip_path) as zip_file: |
| 331 for path in zip_file.namelist(): |
| 332 if re.search(r'[/-]drawable[/-]', path) and naive_predicate(path): |
| 333 non_xxxhdpi_drawables.add(_ResourceNameFromPath(path)) |
| 334 |
| 335 return lambda path: (naive_predicate(path) or |
| 336 _ResourceNameFromPath(path) not in non_xxxhdpi_drawables) |
| 337 |
| 338 |
305 def _OnStaleMd5(package_command, options): | 339 def _OnStaleMd5(package_command, options): |
306 with build_utils.TempDir() as temp_dir: | 340 with build_utils.TempDir() as temp_dir: |
307 if options.resource_zips: | 341 if options.resource_zips: |
308 dep_zips = options.resource_zips | 342 dep_zips = options.resource_zips |
| 343 extract_predicate = _CreateExtractPredicate( |
| 344 dep_zips, options.exclude_xxxhdpi, options.xxxhdpi_whitelist) |
309 for z in dep_zips: | 345 for z in dep_zips: |
310 subdir = os.path.join(temp_dir, os.path.basename(z)) | 346 subdir = os.path.join(temp_dir, os.path.basename(z)) |
311 if os.path.exists(subdir): | 347 if os.path.exists(subdir): |
312 raise Exception('Resource zip name conflict: ' + os.path.basename(z)) | 348 raise Exception('Resource zip name conflict: ' + os.path.basename(z)) |
313 build_utils.ExtractAll(z, path=subdir) | 349 if build_utils.ExtractAll(z, path=subdir, predicate=extract_predicate): |
314 package_command += PackageArgsForExtractedZip(subdir) | 350 package_command += PackageArgsForExtractedZip(subdir) |
315 | 351 |
316 build_utils.CheckOutput( | 352 build_utils.CheckOutput( |
317 package_command, print_stdout=False, print_stderr=False) | 353 package_command, print_stdout=False, print_stderr=False) |
318 | 354 |
319 if options.create_density_splits or options.language_splits: | 355 if options.create_density_splits or options.language_splits: |
320 CheckForMissedConfigs(options.apk_path, options.create_density_splits, | 356 CheckForMissedConfigs(options.apk_path, options.create_density_splits, |
321 options.language_splits) | 357 options.language_splits) |
322 | 358 |
323 if options.create_density_splits: | 359 if options.create_density_splits: |
324 RenameDensitySplits(options.apk_path) | 360 RenameDensitySplits(options.apk_path) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 build_utils.CallAndWriteDepfileIfStale( | 394 build_utils.CallAndWriteDepfileIfStale( |
359 lambda: _OnStaleMd5(package_command, options), | 395 lambda: _OnStaleMd5(package_command, options), |
360 options, | 396 options, |
361 input_paths=input_paths, | 397 input_paths=input_paths, |
362 input_strings=input_strings, | 398 input_strings=input_strings, |
363 output_paths=output_paths) | 399 output_paths=output_paths) |
364 | 400 |
365 | 401 |
366 if __name__ == '__main__': | 402 if __name__ == '__main__': |
367 main(sys.argv[1:]) | 403 main(sys.argv[1:]) |
OLD | NEW |