#!/usr/bin/env python3
#
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Compile Android resources into an intermediate APK.

This can also generate an R.txt, and an .srcjar file containing the proper
final R.java class for all resource packages the APK depends on.

This will crunch images with aapt2.
"""

import argparse
import collections
import contextlib
import filecmp
import hashlib
import logging
import os
import re
import shutil
import subprocess
import sys
import tempfile
import textwrap
import zipfile
from xml.etree import ElementTree

from util import build_utils
from util import diff_utils
from util import manifest_utils
from util import parallel
from util import protoresources
from util import resource_utils


# Pngs that we shouldn't convert to webp. Please add rationale when updating.
_PNG_WEBP_EXCLUSION_PATTERN = re.compile('|'.join([
    # Crashes on Galaxy S5 running L (https://crbug.com/807059).
    r'.*star_gray\.png',
    # Android requires pngs for 9-patch images.
    r'.*\.9\.png',
    # Daydream requires pngs for icon files.
    r'.*daydream_icon_.*\.png'
]))


def _ParseArgs(args):
  """Parses command line options.

  Returns:
    An options object as from argparse.ArgumentParser.parse_args()
  """
  parser, input_opts, output_opts = resource_utils.ResourceArgsParser()

  input_opts.add_argument(
      '--aapt2-path', required=True, help='Path to the Android aapt2 tool.')
  input_opts.add_argument(
      '--android-manifest', required=True, help='AndroidManifest.xml path.')
  input_opts.add_argument(
      '--r-java-root-package-name',
      default='base',
      help='Short package name for this target\'s root R java file (ex. '
      'input of "base" would become gen.base_module). Defaults to "base".')
  group = input_opts.add_mutually_exclusive_group()
  group.add_argument(
      '--shared-resources',
      action='store_true',
      help='Make all resources in R.java non-final and allow the resource IDs '
      'to be reset to a different package index when the apk is loaded by '
      'another application at runtime.')
  group.add_argument(
      '--app-as-shared-lib',
      action='store_true',
      help='Same as --shared-resources, but also ensures all resource IDs are '
      'directly usable from the APK loaded as an application.')

  input_opts.add_argument(
      '--package-id',
      type=int,
      help='Decimal integer representing custom package ID for resources '
      '(instead of 127==0x7f). Cannot be used with --shared-resources.')

  input_opts.add_argument(
      '--package-name',
      help='Package name that will be used to create R class.')

  input_opts.add_argument(
      '--rename-manifest-package', help='Package name to force AAPT to use.')

  input_opts.add_argument(
      '--arsc-package-name',
      help='Package name to set in manifest of resources.arsc file. This is '
      'only used for apks under test.')

  input_opts.add_argument(
      '--shared-resources-allowlist',
      help='An R.txt file acting as a allowlist for resources that should be '
      'non-final and have their package ID changed at runtime in R.java. '
      'Implies and overrides --shared-resources.')

  input_opts.add_argument(
      '--shared-resources-allowlist-locales',
      default='[]',
      help='Optional GN-list of locales. If provided, all strings corresponding'
      ' to this locale list will be kept in the final output for the '
      'resources identified through --shared-resources-allowlist, even '
      'if --locale-allowlist is being used.')

  input_opts.add_argument(
      '--use-resource-ids-path',
      help='Use resource IDs generated by aapt --emit-ids.')

  input_opts.add_argument(
      '--extra-main-r-text-files',
      help='Additional R.txt files that will be added to the root R.java file, '
      'but not packaged in the generated resources.arsc. If these resources '
      'entries contain duplicate resources with the generated R.txt file, they '
      'must be identical.')

  input_opts.add_argument(
      '--support-zh-hk',
      action='store_true',
      help='Use zh-rTW resources for zh-rHK.')

  input_opts.add_argument(
      '--debuggable',
      action='store_true',
      help='Whether to add android:debuggable="true".')

  input_opts.add_argument('--version-code', help='Version code for apk.')
  input_opts.add_argument('--version-name', help='Version name for apk.')
  input_opts.add_argument(
      '--min-sdk-version', required=True, help='android:minSdkVersion for APK.')
  input_opts.add_argument(
      '--target-sdk-version',
      required=True,
      help="android:targetSdkVersion for APK.")
  input_opts.add_argument(
      '--max-sdk-version',
      help="android:maxSdkVersion expected in AndroidManifest.xml.")
  input_opts.add_argument(
      '--manifest-package', help='Package name of the AndroidManifest.xml.')

  input_opts.add_argument(
      '--locale-allowlist',
      default='[]',
      help='GN list of languages to include. All other language configs will '
      'be stripped out. List may include a combination of Android locales '
      'or Chrome locales.')
  input_opts.add_argument(
      '--resource-exclusion-regex',
      default='',
      help='File-based filter for resources (applied before compiling)')
  input_opts.add_argument(
      '--resource-exclusion-exceptions',
      default='[]',
      help='GN list of globs that say which files to include even '
      'when --resource-exclusion-regex is set.')

  input_opts.add_argument(
      '--dependencies-res-zip-overlays',
      help='GN list with subset of --dependencies-res-zips to use overlay '
      'semantics for.')

  input_opts.add_argument(
      '--values-filter-rules',
      help='GN list of source_glob:regex for filtering resources after they '
      'are compiled. Use this to filter out entries within values/ files.')

  input_opts.add_argument('--png-to-webp', action='store_true',
                          help='Convert png files to webp format.')

  input_opts.add_argument('--webp-binary', default='',
                          help='Path to the cwebp binary.')
  input_opts.add_argument(
      '--webp-cache-dir', help='The directory to store webp image cache.')

  input_opts.add_argument(
      '--no-xml-namespaces',
      action='store_true',
      help='Whether to strip xml namespaces from processed xml resources.')
  input_opts.add_argument(
      '--short-resource-paths',
      action='store_true',
      help='Whether to shorten resource paths inside the apk or module.')
  input_opts.add_argument(
      '--strip-resource-names',
      action='store_true',
      help='Whether to strip resource names from the resource table of the apk '
      'or module.')

  output_opts.add_argument('--arsc-path', help='Apk output for arsc format.')
  output_opts.add_argument('--proto-path', help='Apk output for proto format.')
  group = input_opts.add_mutually_exclusive_group()
  group.add_argument(
      '--optimized-arsc-path',
      help='Output for `aapt2 optimize` for arsc format (enables the step).')
  group.add_argument(
      '--optimized-proto-path',
      help='Output for `aapt2 optimize` for proto format (enables the step).')
  input_opts.add_argument(
      '--resources-config-paths',
      default='[]',
      help='GN list of paths to aapt2 resources config files.')

  output_opts.add_argument(
      '--info-path', help='Path to output info file for the partial apk.')

  output_opts.add_argument(
      '--srcjar-out',
      required=True,
      help='Path to srcjar to contain generated R.java.')

  output_opts.add_argument('--r-text-out',
                           help='Path to store the generated R.txt file.')

  output_opts.add_argument(
      '--proguard-file', help='Path to proguard.txt generated file.')

  output_opts.add_argument(
      '--proguard-file-main-dex',
      help='Path to proguard.txt generated file for main dex.')

  output_opts.add_argument(
      '--emit-ids-out', help='Path to file produced by aapt2 --emit-ids.')

  output_opts.add_argument(
      '--resources-path-map-out-path',
      help='Path to file produced by aapt2 that maps original resource paths '
      'to shortened resource paths inside the apk or module.')

  input_opts.add_argument(
      '--is-bundle-module',
      action='store_true',
      help='Whether resources are being generated for a bundle module.')

  input_opts.add_argument(
      '--uses-split',
      help='Value to set uses-split to in the AndroidManifest.xml.')

  input_opts.add_argument(
      '--extra-verification-manifest',
      help='Path to AndroidManifest.xml which should be merged into base '
      'manifest when performing verification.')

  diff_utils.AddCommandLineFlags(parser)
  options = parser.parse_args(args)

  resource_utils.HandleCommonOptions(options)

  options.locale_allowlist = build_utils.ParseGnList(options.locale_allowlist)
  options.shared_resources_allowlist_locales = build_utils.ParseGnList(
      options.shared_resources_allowlist_locales)
  options.resource_exclusion_exceptions = build_utils.ParseGnList(
      options.resource_exclusion_exceptions)
  options.dependencies_res_zip_overlays = build_utils.ParseGnList(
      options.dependencies_res_zip_overlays)
  options.values_filter_rules = build_utils.ParseGnList(
      options.values_filter_rules)
  options.extra_main_r_text_files = build_utils.ParseGnList(
      options.extra_main_r_text_files)
  options.resources_config_paths = build_utils.ParseGnList(
      options.resources_config_paths)

  if options.optimized_proto_path and not options.proto_path:
    # We could write to a temp file, but it's simpler to require it.
    parser.error('--optimized-proto-path requires --proto-path')

  if not options.arsc_path and not options.proto_path:
    parser.error('One of --arsc-path or --proto-path is required.')

  if options.resources_path_map_out_path and not options.short_resource_paths:
    parser.error(
        '--resources-path-map-out-path requires --short-resource-paths')

  if options.package_id and options.shared_resources:
    parser.error('--package-id and --shared-resources are mutually exclusive')

  return options


def _IterFiles(root_dir):
  for root, _, files in os.walk(root_dir):
    for f in files:
      yield os.path.join(root, f)


def _DuplicateZhResources(resource_dirs, path_info):
  """Duplicate Taiwanese resources into Hong-Kong specific directory."""
  for resource_dir in resource_dirs:
    # We use zh-TW resources for zh-HK (if we have zh-TW resources).
    for path in _IterFiles(resource_dir):
      if 'zh-rTW' in path:
        hk_path = path.replace('zh-rTW', 'zh-rHK')
        build_utils.MakeDirectory(os.path.dirname(hk_path))
        shutil.copyfile(path, hk_path)
        path_info.RegisterRename(
            os.path.relpath(path, resource_dir),
            os.path.relpath(hk_path, resource_dir))


def _RenameLocaleResourceDirs(resource_dirs, path_info):
  """Rename locale resource directories into standard names when necessary.

  This is necessary to deal with the fact that older Android releases only
  support ISO 639-1 two-letter codes, and sometimes even obsolete versions
  of them.

  In practice it means:
    * 3-letter ISO 639-2 qualifiers are renamed under a corresponding
      2-letter one. E.g. for Filipino, strings under values-fil/ will be moved
      to a new corresponding values-tl/ sub-directory.

    * Modern ISO 639-1 codes will be renamed to their obsolete variant
      for Indonesian, Hebrew and Yiddish (e.g. 'values-in/ -> values-id/).

    * Norwegian macrolanguage strings will be renamed to Bokmal (main
      Norway language). See http://crbug.com/920960. In practice this
      means that 'values-no/ -> values-nb/' unless 'values-nb/' already
      exists.

    * BCP 47 langauge tags will be renamed to an equivalent ISO 639-1
      locale qualifier if possible (e.g. 'values-b+en+US/ -> values-en-rUS').
      Though this is not necessary at the moment, because no third-party
      package that Chromium links against uses these for the current list of
      supported locales, this may change when the list is extended in the
      future).

  Args:
    resource_dirs: list of top-level resource directories.
  """
  for resource_dir in resource_dirs:
    for path in _IterFiles(resource_dir):
      locale = resource_utils.FindLocaleInStringResourceFilePath(path)
      if not locale:
        continue
      cr_locale = resource_utils.ToChromiumLocaleName(locale)
      if not cr_locale:
        continue  # Unsupported Android locale qualifier!?
      locale2 = resource_utils.ToAndroidLocaleName(cr_locale)
      if locale != locale2:
        path2 = path.replace('/values-%s/' % locale, '/values-%s/' % locale2)
        if path == path2:
          raise Exception('Could not substitute locale %s for %s in %s' %
                          (locale, locale2, path))
        if os.path.exists(path2):
          # This happens sometimes, e.g. some libraries provide both
          # values-nb/ and values-no/ with the same content.
          continue
        build_utils.MakeDirectory(os.path.dirname(path2))
        shutil.move(path, path2)
        path_info.RegisterRename(
            os.path.relpath(path, resource_dir),
            os.path.relpath(path2, resource_dir))


def _ToAndroidLocales(locale_allowlist, support_zh_hk):
  """Converts the list of Chrome locales to Android config locale qualifiers.

  Args:
    locale_allowlist: A list of Chromium locale names.
    support_zh_hk: True if we need to support zh-HK by duplicating
      the zh-TW strings.
  Returns:
    A set of matching Android config locale qualifier names.
  """
  ret = set()
  for locale in locale_allowlist:
    locale = resource_utils.ToAndroidLocaleName(locale)
    if locale is None or ('-' in locale and '-r' not in locale):
      raise Exception('Unsupported Chromium locale name: %s' % locale)
    ret.add(locale)
    # Always keep non-regional fall-backs.
    language = locale.split('-')[0]
    ret.add(language)

  # We don't actually support zh-HK in Chrome on Android, but we mimic the
  # native side behavior where we use zh-TW resources when the locale is set to
  # zh-HK. See https://crbug.com/780847.
  if support_zh_hk:
    assert not any('HK' in l for l in locale_allowlist), (
        'Remove special logic if zh-HK is now supported (crbug.com/780847).')
    ret.add('zh-rHK')
  return set(ret)


def _MoveImagesToNonMdpiFolders(res_root, path_info):
  """Move images from drawable-*-mdpi-* folders to drawable-* folders.

  Why? http://crbug.com/289843
  """
  for src_dir_name in os.listdir(res_root):
    src_components = src_dir_name.split('-')
    if src_components[0] != 'drawable' or 'mdpi' not in src_components:
      continue
    src_dir = os.path.join(res_root, src_dir_name)
    if not os.path.isdir(src_dir):
      continue
    dst_components = [c for c in src_components if c != 'mdpi']
    assert dst_components != src_components
    dst_dir_name = '-'.join(dst_components)
    dst_dir = os.path.join(res_root, dst_dir_name)
    build_utils.MakeDirectory(dst_dir)
    for src_file_name in os.listdir(src_dir):
      if not os.path.splitext(src_file_name)[1] in ('.png', '.webp', ''):
        continue
      src_file = os.path.join(src_dir, src_file_name)
      dst_file = os.path.join(dst_dir, src_file_name)
      assert not os.path.lexists(dst_file)
      shutil.move(src_file, dst_file)
      path_info.RegisterRename(
          os.path.relpath(src_file, res_root),
          os.path.relpath(dst_file, res_root))


def _FixManifest(options, temp_dir, extra_manifest=None):
  """Fix the APK's AndroidManifest.xml.

  This adds any missing namespaces for 'android' and 'tools', and
  sets certains elements like 'platformBuildVersionCode' or
  'android:debuggable' depending on the content of |options|.

  Args:
    options: The command-line arguments tuple.
    temp_dir: A temporary directory where the fixed manifest will be written to.
    extra_manifest: Path to an AndroidManifest.xml file which will get merged
        into the application node of the base manifest.
  Returns:
    Tuple of:
     * Manifest path within |temp_dir|.
     * Original package_name.
  """
  def maybe_extract_version(j):
    try:
      return resource_utils.ExtractBinaryManifestValues(options.aapt2_path, j)
    except build_utils.CalledProcessError:
      return None

  android_sdk_jars = [j for j in options.include_resources
                      if os.path.basename(j) in ('android.jar',
                                                 'android_system.jar')]
  extract_all = [maybe_extract_version(j) for j in android_sdk_jars]
  successful_extractions = [x for x in extract_all if x]
  if len(successful_extractions) == 0:
    raise Exception(
        'Unable to find android SDK jar among candidates: %s'
            % ', '.join(android_sdk_jars))
  elif len(successful_extractions) > 1:
    raise Exception(
        'Found multiple android SDK jars among candidates: %s'
            % ', '.join(android_sdk_jars))
  version_code, version_name = successful_extractions.pop()[:2]

  debug_manifest_path = os.path.join(temp_dir, 'AndroidManifest.xml')
  doc, manifest_node, app_node = manifest_utils.ParseManifest(
      options.android_manifest)

  if extra_manifest:
    _, extra_manifest_node, extra_app_node = manifest_utils.ParseManifest(
        extra_manifest)
    for node in extra_app_node:
      app_node.append(node)
    for node in extra_manifest_node:
      # DFM manifests have a bunch of tags we don't care about inside
      # <manifest>, so only take <queries>.
      if node.tag == 'queries':
        manifest_node.append(node)

  manifest_utils.AssertUsesSdk(manifest_node, options.min_sdk_version,
                               options.target_sdk_version)
  # We explicitly check that maxSdkVersion is set in the manifest since we don't
  # add it later like minSdkVersion and targetSdkVersion.
  manifest_utils.AssertUsesSdk(
      manifest_node,
      max_sdk_version=options.max_sdk_version,
      fail_if_not_exist=True)
  manifest_utils.AssertPackage(manifest_node, options.manifest_package)

  manifest_node.set('platformBuildVersionCode', version_code)
  manifest_node.set('platformBuildVersionName', version_name)

  orig_package = manifest_node.get('package')
  if options.arsc_package_name:
    manifest_node.set('package', options.arsc_package_name)

  if options.debuggable:
    app_node.set('{%s}%s' % (manifest_utils.ANDROID_NAMESPACE, 'debuggable'),
                 'true')

  if options.uses_split:
    uses_split = ElementTree.SubElement(manifest_node, 'uses-split')
    uses_split.set('{%s}name' % manifest_utils.ANDROID_NAMESPACE,
                   options.uses_split)

  # Make sure the min-sdk condition is not less than the min-sdk of the bundle.
  for min_sdk_node in manifest_node.iter('{%s}min-sdk' %
                                         manifest_utils.DIST_NAMESPACE):
    dist_value = '{%s}value' % manifest_utils.DIST_NAMESPACE
    if int(min_sdk_node.get(dist_value)) < int(options.min_sdk_version):
      min_sdk_node.set(dist_value, options.min_sdk_version)

  manifest_utils.SaveManifest(doc, debug_manifest_path)
  return debug_manifest_path, orig_package


def _CreateKeepPredicate(resource_exclusion_regex,
                         resource_exclusion_exceptions):
  """Return a predicate lambda to determine which resource files to keep.

  Args:
    resource_exclusion_regex: A regular expression describing all resources
      to exclude, except if they are mip-maps, or if they are listed
      in |resource_exclusion_exceptions|.
    resource_exclusion_exceptions: A list of glob patterns corresponding
      to exceptions to the |resource_exclusion_regex|.
  Returns:
    A lambda that takes a path, and returns true if the corresponding file
    must be kept.
  """
  predicate = lambda path: os.path.basename(path)[0] != '.'
  if resource_exclusion_regex == '':
    # Do not extract dotfiles (e.g. ".gitkeep"). aapt ignores them anyways.
    return predicate

  # A simple predicate that only removes (returns False for) paths covered by
  # the exclusion regex or listed as exceptions.
  return lambda path: (
      not re.search(resource_exclusion_regex, path) or
      build_utils.MatchesGlob(path, resource_exclusion_exceptions))


def _ComputeSha1(path):
  with open(path, 'rb') as f:
    data = f.read()
  return hashlib.sha1(data).hexdigest()


def _ConvertToWebPSingle(png_path, cwebp_binary, cwebp_version, webp_cache_dir):
  sha1_hash = _ComputeSha1(png_path)

  # The set of arguments that will appear in the cache key.
  quality_args = ['-m', '6', '-q', '100', '-lossless']

  webp_cache_path = os.path.join(
      webp_cache_dir, '{}-{}-{}'.format(sha1_hash, cwebp_version,
                                        ''.join(quality_args)))
  # No need to add .webp. Android can load images fine without them.
  webp_path = os.path.splitext(png_path)[0]

  cache_hit = os.path.exists(webp_cache_path)
  if cache_hit:
    os.link(webp_cache_path, webp_path)
  else:
    # We place the generated webp image to webp_path, instead of in the
    # webp_cache_dir to avoid concurrency issues.
    args = [cwebp_binary, png_path, '-o', webp_path, '-quiet'] + quality_args
    subprocess.check_call(args)

    try:
      os.link(webp_path, webp_cache_path)
    except OSError:
      # Because of concurrent run, a webp image may already exists in
      # webp_cache_path.
      pass

  os.remove(png_path)
  original_dir = os.path.dirname(os.path.dirname(png_path))
  rename_tuple = (os.path.relpath(png_path, original_dir),
                  os.path.relpath(webp_path, original_dir))
  return rename_tuple, cache_hit


def _ConvertToWebP(cwebp_binary, png_paths, path_info, webp_cache_dir):
  cwebp_version = subprocess.check_output([cwebp_binary, '-version']).rstrip()
  shard_args = [(f, ) for f in png_paths
                if not _PNG_WEBP_EXCLUSION_PATTERN.match(f)]

  build_utils.MakeDirectory(webp_cache_dir)
  results = parallel.BulkForkAndCall(_ConvertToWebPSingle,
                                     shard_args,
                                     cwebp_binary=cwebp_binary,
                                     cwebp_version=cwebp_version,
                                     webp_cache_dir=webp_cache_dir)
  total_cache_hits = 0
  for rename_tuple, cache_hit in results:
    path_info.RegisterRename(*rename_tuple)
    total_cache_hits += int(cache_hit)

  logging.debug('png->webp cache: %d/%d', total_cache_hits, len(shard_args))


def _RemoveImageExtensions(directory, path_info):
  """Remove extensions from image files in the passed directory.

  This reduces binary size but does not affect android's ability to load the
  images.
  """
  for f in _IterFiles(directory):
    if (f.endswith('.png') or f.endswith('.webp')) and not f.endswith('.9.png'):
      path_with_extension = f
      path_no_extension = os.path.splitext(path_with_extension)[0]
      if path_no_extension != path_with_extension:
        shutil.move(path_with_extension, path_no_extension)
        path_info.RegisterRename(
            os.path.relpath(path_with_extension, directory),
            os.path.relpath(path_no_extension, directory))


def _CompileSingleDep(index, dep_subdir, keep_predicate, aapt2_path,
                      partials_dir):
  unique_name = '{}_{}'.format(index, os.path.basename(dep_subdir))
  partial_path = os.path.join(partials_dir, '{}.zip'.format(unique_name))

  compile_command = [
      aapt2_path,
      'compile',
      # TODO(wnwen): Turn this on once aapt2 forces 9-patch to be crunched.
      # '--no-crunch',
      '--dir',
      dep_subdir,
      '-o',
      partial_path
  ]

  # There are resources targeting API-versions lower than our minapi. For
  # various reasons it's easier to let aapt2 ignore these than for us to
  # remove them from our build (e.g. it's from a 3rd party library).
  build_utils.CheckOutput(
      compile_command,
      stderr_filter=lambda output: build_utils.FilterLines(
          output, r'ignoring configuration .* for (styleable|attribute)'))

  # Filtering these files is expensive, so only apply filters to the partials
  # that have been explicitly targeted.
  if keep_predicate:
    logging.debug('Applying .arsc filtering to %s', dep_subdir)
    protoresources.StripUnwantedResources(partial_path, keep_predicate)
  return partial_path


def _CreateValuesKeepPredicate(exclusion_rules, dep_subdir):
  patterns = [
      x[1] for x in exclusion_rules
      if build_utils.MatchesGlob(dep_subdir, [x[0]])
  ]
  if not patterns:
    return None

  regexes = [re.compile(p) for p in patterns]
  return lambda x: not any(r.search(x) for r in regexes)


def _CompileDeps(aapt2_path, dep_subdirs, dep_subdir_overlay_set, temp_dir,
                 exclusion_rules):
  partials_dir = os.path.join(temp_dir, 'partials')
  build_utils.MakeDirectory(partials_dir)

  job_params = [(i, dep_subdir,
                 _CreateValuesKeepPredicate(exclusion_rules, dep_subdir))
                for i, dep_subdir in enumerate(dep_subdirs)]

  # Filtering is slow, so ensure jobs with keep_predicate are started first.
  job_params.sort(key=lambda x: not x[2])
  partials = list(
      parallel.BulkForkAndCall(_CompileSingleDep,
                               job_params,
                               aapt2_path=aapt2_path,
                               partials_dir=partials_dir))

  partials_cmd = list()
  for i, partial in enumerate(partials):
    dep_subdir = job_params[i][1]
    if dep_subdir in dep_subdir_overlay_set:
      partials_cmd += ['-R']
    partials_cmd += [partial]
  return partials_cmd


def _CreateResourceInfoFile(path_info, info_path, dependencies_res_zips):
  for zip_file in dependencies_res_zips:
    zip_info_file_path = zip_file + '.info'
    if os.path.exists(zip_info_file_path):
      path_info.MergeInfoFile(zip_info_file_path)
  path_info.Write(info_path)


def _RemoveUnwantedLocalizedStrings(dep_subdirs, options):
  """Remove localized strings that should not go into the final output.

  Args:
    dep_subdirs: List of resource dependency directories.
    options: Command-line options namespace.
  """
  # Collect locale and file paths from the existing subdirs.
  # The following variable maps Android locale names to
  # sets of corresponding xml file paths.
  locale_to_files_map = collections.defaultdict(set)
  for directory in dep_subdirs:
    for f in _IterFiles(directory):
      locale = resource_utils.FindLocaleInStringResourceFilePath(f)
      if locale:
        locale_to_files_map[locale].add(f)

  all_locales = set(locale_to_files_map)

  # Set A: wanted locales, either all of them or the
  # list provided by --locale-allowlist.
  wanted_locales = all_locales
  if options.locale_allowlist:
    wanted_locales = _ToAndroidLocales(options.locale_allowlist,
                                       options.support_zh_hk)

  # Set B: shared resources locales, which is either set A
  # or the list provided by --shared-resources-allowlist-locales
  shared_resources_locales = wanted_locales
  shared_names_allowlist = set()
  if options.shared_resources_allowlist_locales:
    shared_names_allowlist = set(
        resource_utils.GetRTxtStringResourceNames(
            options.shared_resources_allowlist))

    shared_resources_locales = _ToAndroidLocales(
        options.shared_resources_allowlist_locales, options.support_zh_hk)

  # Remove any file that belongs to a locale not covered by
  # either A or B.
  removable_locales = (all_locales - wanted_locales - shared_resources_locales)
  for locale in removable_locales:
    for path in locale_to_files_map[locale]:
      os.remove(path)

  # For any locale in B but not in A, only keep the shared
  # resource strings in each file.
  for locale in shared_resources_locales - wanted_locales:
    for path in locale_to_files_map[locale]:
      resource_utils.FilterAndroidResourceStringsXml(
          path, lambda x: x in shared_names_allowlist)

  # For any locale in A but not in B, only keep the strings
  # that are _not_ from shared resources in the file.
  for locale in wanted_locales - shared_resources_locales:
    for path in locale_to_files_map[locale]:
      resource_utils.FilterAndroidResourceStringsXml(
          path, lambda x: x not in shared_names_allowlist)


def _FilterResourceFiles(dep_subdirs, keep_predicate):
  # Create a function that selects which resource files should be packaged
  # into the final output. Any file that does not pass the predicate will
  # be removed below.
  png_paths = []
  for directory in dep_subdirs:
    for f in _IterFiles(directory):
      if not keep_predicate(f):
        os.remove(f)
      elif f.endswith('.png'):
        png_paths.append(f)

  return png_paths


def _PackageApk(options, build):
  """Compile and link resources with aapt2.

  Args:
    options: The command-line options.
    build: BuildContext object.
  Returns:
    The manifest package name for the APK.
  """
  logging.debug('Extracting resource .zips')
  dep_subdirs = []
  dep_subdir_overlay_set = set()
  for dependency_res_zip in options.dependencies_res_zips:
    extracted_dep_subdirs = resource_utils.ExtractDeps([dependency_res_zip],
                                                       build.deps_dir)
    dep_subdirs += extracted_dep_subdirs
    if dependency_res_zip in options.dependencies_res_zip_overlays:
      dep_subdir_overlay_set.update(extracted_dep_subdirs)

  logging.debug('Applying locale transformations')
  path_info = resource_utils.ResourceInfoFile()
  if options.support_zh_hk:
    _DuplicateZhResources(dep_subdirs, path_info)
  _RenameLocaleResourceDirs(dep_subdirs, path_info)

  logging.debug('Applying file-based exclusions')
  keep_predicate = _CreateKeepPredicate(options.resource_exclusion_regex,
                                        options.resource_exclusion_exceptions)
  png_paths = _FilterResourceFiles(dep_subdirs, keep_predicate)

  if options.locale_allowlist or options.shared_resources_allowlist_locales:
    logging.debug('Applying locale-based string exclusions')
    _RemoveUnwantedLocalizedStrings(dep_subdirs, options)

  if png_paths and options.png_to_webp:
    logging.debug('Converting png->webp')
    _ConvertToWebP(options.webp_binary, png_paths, path_info,
                   options.webp_cache_dir)
  logging.debug('Applying drawable transformations')
  for directory in dep_subdirs:
    _MoveImagesToNonMdpiFolders(directory, path_info)
    _RemoveImageExtensions(directory, path_info)

  logging.debug('Running aapt2 compile')
  exclusion_rules = [x.split(':', 1) for x in options.values_filter_rules]
  partials = _CompileDeps(options.aapt2_path, dep_subdirs,
                          dep_subdir_overlay_set, build.temp_dir,
                          exclusion_rules)

  link_command = [
      options.aapt2_path,
      'link',
      '--auto-add-overlay',
      '--no-version-vectors',
      # Set SDK versions in case they are not set in the Android manifest.
      '--min-sdk-version',
      options.min_sdk_version,
      '--target-sdk-version',
      options.target_sdk_version,
  ]

  for j in options.include_resources:
    link_command += ['-I', j]
  if options.version_code:
    link_command += ['--version-code', options.version_code]
  if options.version_name:
    link_command += ['--version-name', options.version_name]
  if options.proguard_file:
    link_command += ['--proguard', build.proguard_path]
    link_command += ['--proguard-minimal-keep-rules']
  if options.proguard_file_main_dex:
    link_command += ['--proguard-main-dex', build.proguard_main_dex_path]
  if options.emit_ids_out:
    link_command += ['--emit-ids', build.emit_ids_path]
  if options.r_text_in:
    shutil.copyfile(options.r_text_in, build.r_txt_path)
  else:
    link_command += ['--output-text-symbols', build.r_txt_path]

  # Note: only one of --proto-format, --shared-lib or --app-as-shared-lib
  #       can be used with recent versions of aapt2.
  if options.shared_resources:
    link_command.append('--shared-lib')

  if options.no_xml_namespaces:
    link_command.append('--no-xml-namespaces')

  if options.package_id:
    link_command += [
        '--package-id',
        hex(options.package_id),
        '--allow-reserved-package-id',
    ]

  fixed_manifest, desired_manifest_package_name = _FixManifest(
      options, build.temp_dir)
  if options.rename_manifest_package:
    desired_manifest_package_name = options.rename_manifest_package

  link_command += [
      '--manifest', fixed_manifest, '--rename-manifest-package',
      desired_manifest_package_name
  ]

  # Creates a .zip with AndroidManifest.xml, resources.arsc, res/*
  # Also creates R.txt
  if options.use_resource_ids_path:
    _CreateStableIdsFile(options.use_resource_ids_path, build.stable_ids_path,
                         desired_manifest_package_name)
    link_command += ['--stable-ids', build.stable_ids_path]

  link_command += partials

  # We always create a binary arsc file first, then convert to proto, so flags
  # such as --shared-lib can be supported.
  arsc_path = build.arsc_path
  if arsc_path is None:
    _, arsc_path = tempfile.mkstmp()
  link_command += ['-o', build.arsc_path]

  logging.debug('Starting: aapt2 link')
  link_proc = subprocess.Popen(link_command)

  # Create .res.info file in parallel.
  _CreateResourceInfoFile(path_info, build.info_path,
                          options.dependencies_res_zips)
  logging.debug('Created .res.info file')

  exit_code = link_proc.wait()
  logging.debug('Finished: aapt2 link')
  if exit_code:
    raise subprocess.CalledProcessError(exit_code, link_command)

  if options.proguard_file and (options.shared_resources
                                or options.app_as_shared_lib):
    # Make sure the R class associated with the manifest package does not have
    # its onResourcesLoaded method obfuscated or removed, so that the framework
    # can call it in the case where the APK is being loaded as a library.
    with open(build.proguard_path, 'a') as proguard_file:
      keep_rule = '''
                  -keep class {package}.R {{
                    public static void onResourcesLoaded(int);
                  }}
                  '''.format(package=desired_manifest_package_name)
      proguard_file.write(textwrap.dedent(keep_rule))

  logging.debug('Running aapt2 convert')
  build_utils.CheckOutput([
      options.aapt2_path, 'convert', '--output-format', 'proto', '-o',
      build.proto_path, build.arsc_path
  ])

  # Workaround for b/147674078. This is only needed for WebLayer and does not
  # affect WebView usage, since WebView does not used dynamic attributes.
  if options.shared_resources:
    logging.debug('Hardcoding dynamic attributes')
    protoresources.HardcodeSharedLibraryDynamicAttributes(
        build.proto_path, options.is_bundle_module,
        options.shared_resources_allowlist)

    build_utils.CheckOutput([
        options.aapt2_path, 'convert', '--output-format', 'binary', '-o',
        build.arsc_path, build.proto_path
    ])

  if build.arsc_path is None:
    os.remove(arsc_path)

  if options.optimized_proto_path:
    _OptimizeApk(build.optimized_proto_path, options, build.temp_dir,
                 build.proto_path, build.r_txt_path)
  elif options.optimized_arsc_path:
    _OptimizeApk(build.optimized_arsc_path, options, build.temp_dir,
                 build.arsc_path, build.r_txt_path)

  return desired_manifest_package_name


def _CombineResourceConfigs(resources_config_paths, out_config_path):
  with open(out_config_path, 'w') as out_config:
    for config_path in resources_config_paths:
      with open(config_path) as config:
        out_config.write(config.read())
        out_config.write('\n')


def _OptimizeApk(output, options, temp_dir, unoptimized_path, r_txt_path):
  """Optimize intermediate .ap_ file with aapt2.

  Args:
    output: Path to write to.
    options: The command-line options.
    temp_dir: A temporary directory.
    unoptimized_path: path of the apk to optimize.
    r_txt_path: path to the R.txt file of the unoptimized apk.
  """
  optimize_command = [
      options.aapt2_path,
      'optimize',
      unoptimized_path,
      '-o',
      output,
  ]

  # Optimize the resources.arsc file by obfuscating resource names and only
  # allow usage via R.java constant.
  if options.strip_resource_names:
    no_collapse_resources = _ExtractNonCollapsableResources(r_txt_path)
    gen_config_path = os.path.join(temp_dir, 'aapt2.config')
    if options.resources_config_paths:
      _CombineResourceConfigs(options.resources_config_paths, gen_config_path)
    with open(gen_config_path, 'a') as config:
      for resource in no_collapse_resources:
        config.write('{}#no_collapse\n'.format(resource))

    optimize_command += [
        '--collapse-resource-names',
        '--resources-config-path',
        gen_config_path,
    ]

  if options.short_resource_paths:
    optimize_command += ['--shorten-resource-paths']
  if options.resources_path_map_out_path:
    optimize_command += [
        '--resource-path-shortening-map', options.resources_path_map_out_path
    ]

  logging.debug('Running aapt2 optimize')
  build_utils.CheckOutput(
      optimize_command, print_stdout=False, print_stderr=False)


def _ExtractNonCollapsableResources(rtxt_path):
  """Extract resources that should not be collapsed from the R.txt file

  Resources of type ID are references to UI elements/views. They are used by
  UI automation testing frameworks. They are kept in so that they don't break
  tests, even though they may not actually be used during runtime. See
  https://crbug.com/900993
  App icons (aka mipmaps) are sometimes referenced by other apps by name so must
  be keps as well. See https://b/161564466

  Args:
    rtxt_path: Path to R.txt file with all the resources
  Returns:
    List of resources in the form of <resource_type>/<resource_name>
  """
  resources = []
  _NO_COLLAPSE_TYPES = ['id', 'mipmap']
  with open(rtxt_path) as rtxt:
    for line in rtxt:
      for resource_type in _NO_COLLAPSE_TYPES:
        if ' {} '.format(resource_type) in line:
          resource_name = line.split()[2]
          resources.append('{}/{}'.format(resource_type, resource_name))
  return resources


@contextlib.contextmanager
def _CreateStableIdsFile(in_path, out_path, package_name):
  """Transforms a file generated by --emit-ids from another package.

  --stable-ids is generally meant to be used by different versions of the same
  package. To make it work for other packages, we need to transform the package
  name references to match the package that resources are being generated for.

  Note: This will fail if the package ID of the resources in
  |options.use_resource_ids_path| does not match the package ID of the
  resources being linked.
  """
  with open(in_path) as stable_ids_file:
    with open(out_path, 'w') as output_ids_file:
      output_stable_ids = re.sub(
          r'^.*?:',
          package_name + ':',
          stable_ids_file.read(),
          flags=re.MULTILINE)
      output_ids_file.write(output_stable_ids)


def _WriteOutputs(options, build):
  possible_outputs = [
      (options.srcjar_out, build.srcjar_path),
      (options.r_text_out, build.r_txt_path),
      (options.arsc_path, build.arsc_path),
      (options.proto_path, build.proto_path),
      (options.optimized_arsc_path, build.optimized_arsc_path),
      (options.optimized_proto_path, build.optimized_proto_path),
      (options.proguard_file, build.proguard_path),
      (options.proguard_file_main_dex, build.proguard_main_dex_path),
      (options.emit_ids_out, build.emit_ids_path),
      (options.info_path, build.info_path),
  ]

  for final, temp in possible_outputs:
    # Write file only if it's changed.
    if final and not (os.path.exists(final) and filecmp.cmp(final, temp)):
      shutil.move(temp, final)


def _CreateNormalizedManifestForVerification(options):
  with build_utils.TempDir() as tempdir:
    fixed_manifest, _ = _FixManifest(
        options, tempdir, extra_manifest=options.extra_verification_manifest)
    with open(fixed_manifest) as f:
      return manifest_utils.NormalizeManifest(f.read())


def main(args):
  build_utils.InitLogging('RESOURCE_DEBUG')
  args = build_utils.ExpandFileArgs(args)
  options = _ParseArgs(args)

  if options.expected_file:
    actual_data = _CreateNormalizedManifestForVerification(options)
    diff_utils.CheckExpectations(actual_data, options)
    if options.only_verify_expectations:
      return

  path = options.arsc_path or options.proto_path
  debug_temp_resources_dir = os.environ.get('TEMP_RESOURCES_DIR')
  if debug_temp_resources_dir:
    path = os.path.join(debug_temp_resources_dir, os.path.basename(path))
  else:
    # Use a deterministic temp directory since .pb files embed the absolute
    # path of resources: crbug.com/939984
    path = path + '.tmpdir'
  build_utils.DeleteDirectory(path)

  with resource_utils.BuildContext(
      temp_dir=path, keep_files=bool(debug_temp_resources_dir)) as build:

    manifest_package_name = _PackageApk(options, build)

    # If --shared-resources-allowlist is used, all the resources listed in the
    # corresponding R.txt file will be non-final, and an onResourcesLoaded()
    # will be generated to adjust them at runtime.
    #
    # Otherwise, if --shared-resources is used, the all resources will be
    # non-final, and an onResourcesLoaded() method will be generated too.
    #
    # Otherwise, all resources will be final, and no method will be generated.
    #
    rjava_build_options = resource_utils.RJavaBuildOptions()
    if options.shared_resources_allowlist:
      rjava_build_options.ExportSomeResources(
          options.shared_resources_allowlist)
      rjava_build_options.GenerateOnResourcesLoaded()
      if options.shared_resources:
        # The final resources will only be used in WebLayer, so hardcode the
        # package ID to be what WebLayer expects.
        rjava_build_options.SetFinalPackageId(
            protoresources.SHARED_LIBRARY_HARDCODED_ID)
    elif options.shared_resources or options.app_as_shared_lib:
      rjava_build_options.ExportAllResources()
      rjava_build_options.GenerateOnResourcesLoaded()

    custom_root_package_name = options.r_java_root_package_name
    grandparent_custom_package_name = None

    # Always generate an R.java file for the package listed in
    # AndroidManifest.xml because this is where Android framework looks to find
    # onResourcesLoaded() for shared library apks. While not actually necessary
    # for application apks, it also doesn't hurt.
    apk_package_name = manifest_package_name

    if options.package_name and not options.arsc_package_name:
      # Feature modules have their own custom root package name and should
      # inherit from the appropriate base module package. This behaviour should
      # not be present for test apks with an apk under test. Thus,
      # arsc_package_name is used as it is only defined for test apks with an
      # apk under test.
      custom_root_package_name = options.package_name
      grandparent_custom_package_name = options.r_java_root_package_name
      # Feature modules have the same manifest package as the base module but
      # they should not create an R.java for said manifest package because it
      # will be created in the base module.
      apk_package_name = None

    logging.debug('Creating R.srcjar')
    resource_utils.CreateRJavaFiles(
        build.srcjar_dir, apk_package_name, build.r_txt_path,
        options.extra_res_packages, rjava_build_options, options.srcjar_out,
        custom_root_package_name, grandparent_custom_package_name,
        options.extra_main_r_text_files)
    build_utils.ZipDir(build.srcjar_path, build.srcjar_dir)

    # Sanity check that the created resources have the expected package ID.
    logging.debug('Performing sanity check')
    if options.package_id:
      expected_id = options.package_id
    elif options.shared_resources:
      expected_id = 0
    else:
      expected_id = 127  # == '0x7f'.
    _, package_id = resource_utils.ExtractArscPackage(
        options.aapt2_path,
        build.arsc_path if options.arsc_path else build.proto_path)
    if package_id != expected_id:
      raise Exception(
          'Invalid package ID 0x%x (expected 0x%x)' % (package_id, expected_id))

    logging.debug('Copying outputs')
    _WriteOutputs(options, build)

  if options.depfile:
    depfile_deps = (options.dependencies_res_zips +
                    options.dependencies_res_zip_overlays +
                    options.extra_main_r_text_files + options.include_resources)
    build_utils.WriteDepfile(options.depfile, options.srcjar_out, depfile_deps)


if __name__ == '__main__':
  main(sys.argv[1:])
