1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# Do not add any imports to non-//build directories here.
6# Some projects (e.g. V8) do not have non-build directories DEPS'ed in.
7
8import("//build/config/android/channel.gni")
9import("//build/config/android/config.gni")
10import("//build/config/android/internal_rules.gni")
11import("//build/config/clang/clang.gni")
12import("//build/config/compiler/compiler.gni")
13import("//build/config/coverage/coverage.gni")
14import("//build/config/dcheck_always_on.gni")
15import("//build/config/python.gni")
16import("//build/config/zip.gni")
17import("//build/toolchain/toolchain.gni")
18
19assert(is_android)
20
21declare_args() {
22  enable_jni_tracing = false
23}
24
25if (target_cpu == "arm") {
26  _sanitizer_arch = "arm"
27} else if (target_cpu == "arm64") {
28  _sanitizer_arch = "aarch64"
29} else if (target_cpu == "x86") {
30  _sanitizer_arch = "i686"
31}
32
33_sanitizer_runtimes = []
34if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) {
35  _sanitizer_runtimes = [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.ubsan_standalone-$_sanitizer_arch-android.so" ]
36}
37
38# Creates a dist directory for a native executable.
39#
40# Running a native executable on a device requires all the shared library
41# dependencies of that executable. To make it easier to install and run such an
42# executable, this will create a directory containing the native exe and all
43# it's library dependencies.
44#
45# Note: It's usually better to package things as an APK than as a native
46# executable.
47#
48# Variables
49#   dist_dir: Directory for the exe and libraries. Everything in this directory
50#     will be deleted before copying in the exe and libraries.
51#   binary: Path to (stripped) executable.
52#   extra_files: List of extra files to copy in (optional).
53#
54# Example
55#   create_native_executable_dist("foo_dist") {
56#     dist_dir = "$root_build_dir/foo_dist"
57#     binary = "$root_build_dir/foo"
58#     deps = [ ":the_thing_that_makes_foo" ]
59#   }
60template("create_native_executable_dist") {
61  forward_variables_from(invoker, [ "testonly" ])
62
63  _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list"
64
65  _sanitizer_runtimes_target_name = "${target_name}__sanitizer_runtimes"
66  group(_sanitizer_runtimes_target_name) {
67    metadata = {
68      shared_libraries = _sanitizer_runtimes
69    }
70  }
71
72  generated_file("${target_name}__library_list") {
73    forward_variables_from(invoker, [ "deps" ])
74    if (!defined(deps)) {
75      deps = []
76    }
77    deps += [ ":${_sanitizer_runtimes_target_name}" ]
78    output_conversion = "json"
79    outputs = [ _libraries_list ]
80    data_keys = [ "shared_libraries" ]
81    walk_keys = [ "shared_libraries_barrier" ]
82    rebase = root_build_dir
83  }
84
85  copy_ex(target_name) {
86    inputs = [
87      _libraries_list,
88      invoker.binary,
89    ]
90
91    dest = invoker.dist_dir
92    data = [ "${invoker.dist_dir}/" ]
93
94    _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir)
95    _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir)
96    args = [
97      "--clear",
98      "--files=@FileArg($_rebased_libraries_list)",
99      "--files=$_rebased_binaries_list",
100    ]
101    if (defined(invoker.extra_files)) {
102      _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir)
103      args += [ "--files=$_rebased_extra_files" ]
104    }
105
106    _depfile = "$target_gen_dir/$target_name.d"
107    _stamp_file = "$target_gen_dir/$target_name.stamp"
108    outputs = [ _stamp_file ]
109    args += [
110      "--depfile",
111      rebase_path(_depfile, root_build_dir),
112      "--stamp",
113      rebase_path(_stamp_file, root_build_dir),
114    ]
115
116    deps = [ ":${target_name}__library_list" ]
117    if (defined(invoker.deps)) {
118      deps += invoker.deps
119    }
120  }
121}
122
123if (enable_java_templates) {
124  import("//build/config/sanitizers/sanitizers.gni")
125
126  # JNI target implementation. See generate_jni or generate_jar_jni for usage.
127  template("generate_jni_impl") {
128    _jni_output_dir = "${target_gen_dir}/${target_name}"
129    if (defined(invoker.jni_generator_include)) {
130      _jni_generator_include = invoker.jni_generator_include
131      _jni_generator_include_deps = []
132    } else {
133      _jni_generator_include =
134          "//base/android/jni_generator/jni_generator_helper.h"
135      _jni_generator_include_deps = [
136        # Using //base/android/jni_generator/jni_generator_helper.h introduces
137        # a dependency on buildflags targets indirectly through
138        # base/android/jni_android.h, which is part of the //base target.
139        # This can't depend directly on //base without causing a dependency
140        # cycle, though.
141        "//base:debugging_buildflags",
142        "//base:logging_buildflags",
143      ]
144    }
145
146    action_with_pydeps(target_name) {
147      # The sources aren't compiled so don't check their dependencies.
148      check_includes = false
149      script = "//base/android/jni_generator/jni_generator.py"
150      forward_variables_from(invoker,
151                             [
152                               "deps",
153                               "public_deps",
154                               "visibility",
155                               "testonly",
156                             ])
157      if (!defined(public_deps)) {
158        public_deps = []
159      }
160      public_deps += _jni_generator_include_deps
161      inputs = []
162      args = [
163        "--ptr_type=long",
164        "--includes",
165        rebase_path(_jni_generator_include, _jni_output_dir),
166      ]
167
168      if (defined(invoker.classes)) {
169        if (defined(invoker.jar_file)) {
170          _jar_file = invoker.jar_file
171        } else {
172          _jar_file = android_sdk_jar
173        }
174        inputs += [ _jar_file ]
175        args += [
176          "--jar_file",
177          rebase_path(_jar_file, root_build_dir),
178        ]
179        _input_args = invoker.classes
180        _input_names = invoker.classes
181        if (defined(invoker.always_mangle) && invoker.always_mangle) {
182          args += [ "--always_mangle" ]
183        }
184      } else {
185        assert(defined(invoker.sources))
186        inputs += invoker.sources
187        _input_args = rebase_path(invoker.sources, root_build_dir)
188        _input_names = invoker.sources
189        if (use_hashed_jni_names) {
190          args += [ "--use_proxy_hash" ]
191        }
192        if (defined(invoker.namespace)) {
193          args += [ "-n ${invoker.namespace}" ]
194        }
195      }
196
197      outputs = []
198      foreach(_name, _input_names) {
199        _name_part = get_path_info(_name, "name")
200        outputs += [ "${_jni_output_dir}/${_name_part}_jni.h" ]
201      }
202
203      # Avoid passing GN lists because not all webrtc embedders use //build.
204      foreach(_output, outputs) {
205        args += [
206          "--output_file",
207          rebase_path(_output, root_build_dir),
208        ]
209      }
210      foreach(_input, _input_args) {
211        args += [ "--input_file=$_input" ]
212      }
213
214      if (enable_profiling) {
215        args += [ "--enable_profiling" ]
216      }
217      if (enable_jni_tracing) {
218        args += [ "--enable_tracing" ]
219      }
220    }
221  }
222
223  # Declare a jni target
224  #
225  # This target generates the native jni bindings for a set of .java files.
226  #
227  # See base/android/jni_generator/jni_generator.py for more info about the
228  # format of generating JNI bindings.
229  #
230  # Variables
231  #   sources: list of .java files to generate jni for
232  #   namespace: Specify the namespace for the generated header file.
233  #   deps, public_deps: As normal
234  #
235  # Example
236  #   # Target located in base/BUILD.gn.
237  #   generate_jni("foo_jni") {
238  #     # Generates gen/base/foo_jni/Foo_jni.h
239  #     # To use: #include "base/foo_jni/Foo_jni.h"
240  #     sources = [
241  #       "android/java/src/org/chromium/foo/Foo.java",
242  #       ...,
243  #     ]
244  #   }
245  template("generate_jni") {
246    generate_jni_impl(target_name) {
247      forward_variables_from(invoker, "*")
248    }
249  }
250
251  # Declare a jni target for a prebuilt jar
252  #
253  # This target generates the native jni bindings for a set of classes in a .jar.
254  #
255  # See base/android/jni_generator/jni_generator.py for more info about the
256  # format of generating JNI bindings.
257  #
258  # Variables
259  #   classes: list of .class files in the jar to generate jni for. These should
260  #     include the full path to the .class file.
261  #   jar_file: the path to the .jar. If not provided, will default to the sdk's
262  #     android.jar
263  #   always_mangle: Mangle all generated method names. By default, the script
264  #     only mangles methods that cause ambiguity due to method overload.
265  #   deps, public_deps: As normal
266  #
267  # Example
268  #   # Target located in base/BUILD.gn.
269  #   generate_jar_jni("foo_jni") {
270  #     # Generates gen/base/foo_jni/Runnable_jni.h
271  #     # To use: #include "base/foo_jni/Runnable_jni.h"
272  #     classes = [
273  #       "android/view/Foo.class",
274  #     ]
275  #   }
276  template("generate_jar_jni") {
277    generate_jni_impl(target_name) {
278      forward_variables_from(invoker, "*")
279    }
280  }
281
282  # Declare a jni registration target.
283  #
284  # This target generates a srcjar containing a copy of GEN_JNI.java, which has
285  # the native methods of all dependent java files. It can also create a .h file
286  # for use with manual JNI registration.
287  #
288  # The script does not scan any generated sources (those within .srcjars, or
289  # within root_build_dir). This could be fixed by adding deps & logic to scan
290  # .srcjars, but isn't currently needed.
291  #
292  # See base/android/jni_generator/jni_registration_generator.py for more info
293  # about the format of the header file.
294  #
295  # Variables
296  #   targets: List of .build_config supported targets to provide java sources.
297  #   header_output: Path to the generated .h file (optional).
298  #   sources_exclusions: List of .java files that should be skipped. (optional)
299  #   namespace: Registration functions will be wrapped into this. (optional)
300  #   require_native_mocks: Enforce that any native calls using
301  #     org.chromium.base.annotations.NativeMethods must have a mock set
302  #     (optional).
303  #   enable_native_mocks: Allow native calls using
304  #     org.chromium.base.annotations.NativeMethods to be mocked in tests
305  #     (optional).
306  #   no_transitive_deps: Generate registration for only the Java source in the
307  #     specified target(s). This is useful for generating registration for
308  #     feature modules, without including base module dependencies.
309  #
310  # Example
311  #   generate_jni_registration("chrome_jni_registration") {
312  #     targets = [ ":chrome_public_apk" ]
313  #     header_output = "$target_gen_dir/$target_name.h"
314  #     sources_exclusions = [
315  #       "//path/to/Exception.java",
316  #     ]
317  #   }
318  template("generate_jni_registration") {
319    action_with_pydeps(target_name) {
320      forward_variables_from(invoker, [ "testonly" ])
321
322      script = "//base/android/jni_generator/jni_registration_generator.py"
323      inputs = []
324      deps = []
325      _srcjar_output = "$target_gen_dir/$target_name.srcjar"
326      outputs = [ _srcjar_output ]
327      depfile = "$target_gen_dir/$target_name.d"
328
329      args = [
330        "--srcjar-path",
331        rebase_path(_srcjar_output, root_build_dir),
332        "--depfile",
333        rebase_path(depfile, root_build_dir),
334      ]
335      foreach(_target, invoker.targets) {
336        deps += [ "${_target}$build_config_target_suffix($default_toolchain)" ]
337        _build_config =
338            get_label_info("${_target}($default_toolchain)", "target_gen_dir") +
339            "/" + get_label_info("${_target}($default_toolchain)", "name") +
340            ".build_config"
341        _rebased_build_config = rebase_path(_build_config, root_build_dir)
342        inputs += [ _build_config ]
343
344        if (defined(invoker.no_transitive_deps) && invoker.no_transitive_deps) {
345          args += [ "--sources-files=@FileArg($_rebased_build_config:deps_info:java_sources_file)" ]
346        } else {
347          args += [
348            # This is a list of .sources files.
349            "--sources-files=@FileArg($_rebased_build_config:deps_info:jni:all_source)",
350          ]
351        }
352      }
353
354      if (use_hashed_jni_names) {
355        args += [ "--use_proxy_hash" ]
356      }
357
358      if (defined(invoker.enable_native_mocks) && invoker.enable_native_mocks) {
359        args += [ "--enable_proxy_mocks" ]
360
361        if (defined(invoker.require_native_mocks) &&
362            invoker.require_native_mocks) {
363          args += [ "--require_mocks" ]
364        }
365      }
366
367      if (defined(invoker.header_output)) {
368        outputs += [ invoker.header_output ]
369        args += [
370          "--header-path",
371          rebase_path(invoker.header_output, root_build_dir),
372        ]
373      }
374
375      if (defined(invoker.sources_exclusions)) {
376        _rebase_sources_exclusions =
377            rebase_path(invoker.sources_exclusions, root_build_dir)
378        args += [ "--sources-exclusions=$_rebase_sources_exclusions" ]
379      }
380
381      if (defined(invoker.namespace)) {
382        args += [ "--namespace=${invoker.namespace}" ]
383      }
384    }
385  }
386
387  # Declare a target for c-preprocessor-generated java files
388  #
389  # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
390  #       rule instead.
391  #
392  # This target generates java files using the host C pre-processor. Each file in
393  # sources will be compiled using the C pre-processor. If include_path is
394  # specified, it will be passed (with --I) to the pre-processor.
395  #
396  # This target will create a single .srcjar. Adding this target to an
397  # android_library target's srcjar_deps will make the generated java files be
398  # included in that library's final outputs.
399  #
400  # Variables
401  #   sources: list of files to be processed by the C pre-processor. For each
402  #     file in sources, there will be one .java file in the final .srcjar. For a
403  #     file named FooBar.template, a java file will be created with name
404  #     FooBar.java.
405  #   inputs: additional compile-time dependencies. Any files
406  #     `#include`-ed in the templates should be listed here.
407  #   defines: List of -D arguments for the preprocessor.
408  #
409  # Example
410  #   java_cpp_template("foo_generated_enum") {
411  #     sources = [
412  #       "android/java/templates/Foo.template",
413  #     ]
414  #     inputs = [
415  #       "android/java/templates/native_foo_header.h",
416  #     ]
417  #   }
418  template("java_cpp_template") {
419    action_with_pydeps(target_name) {
420      forward_variables_from(invoker,
421                             [
422                               "data_deps",
423                               "deps",
424                               "inputs",
425                               "public_deps",
426                               "sources",
427                               "testonly",
428                               "visibility",
429                             ])
430      script = "//build/android/gyp/gcc_preprocess.py"
431      outputs = [ "$target_gen_dir/$target_name.srcjar" ]
432
433      _include_dirs = [
434        "//",
435        root_gen_dir,
436      ]
437      _rebased_include_dirs = rebase_path(_include_dirs, root_build_dir)
438      args = [
439        "--include-dirs=$_rebased_include_dirs",
440        "--output",
441        rebase_path(outputs[0], root_build_dir),
442      ]
443      if (defined(invoker.defines)) {
444        foreach(_define, invoker.defines) {
445          args += [
446            "--define",
447            _define,
448          ]
449        }
450      }
451      args += rebase_path(sources, root_build_dir)
452    }
453  }
454
455  # Declare a target for generating Java classes from C++ enums.
456  #
457  # This target generates Java files from C++ enums using a script.
458  #
459  # This target will create a single .srcjar. Adding this target to an
460  # android_library target's srcjar_deps will make the generated java files be
461  # included in that library's final outputs.
462  #
463  # Variables
464  #   sources: list of files to be processed by the script. For each annotated
465  #     enum contained in the sources files the script will generate a .java
466  #     file with the same name as the name of the enum.
467  #
468  # Example
469  #   java_cpp_enum("foo_generated_enum") {
470  #     sources = [
471  #       "src/native_foo_header.h",
472  #     ]
473  #   }
474  template("java_cpp_enum") {
475    action_with_pydeps(target_name) {
476      forward_variables_from(invoker,
477                             [
478                               "sources",
479                               "testonly",
480                               "visibility",
481                             ])
482
483      # The sources aren't compiled so don't check their dependencies.
484      check_includes = false
485      script = "//build/android/gyp/java_cpp_enum.py"
486
487      _srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
488      _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir)
489      _rebased_sources = rebase_path(invoker.sources, root_build_dir)
490
491      args = [ "--srcjar=$_rebased_srcjar_path" ] + _rebased_sources
492      outputs = [ _srcjar_path ]
493    }
494  }
495
496  # Declare a target for generating Java classes with string constants matching
497  # those found in C++ files using a python script.
498  #
499  # This target will create a single .srcjar. Adding this target to an
500  # android_library target's srcjar_deps will make the generated java files be
501  # included in that library's final outputs.
502  #
503  # Variables
504  #   sources: list of files to be processed by the script. For each string
505  #            constant in the source files, the script will add a corresponding
506  #            Java string to the specified template file.
507  # Example
508  #   java_cpp_strings("foo_switches") {
509  #     sources = [
510  #       "src/foo_switches.cc",
511  #     ]
512  #     template = "src/templates/FooSwitches.java.tmpl
513  #   }
514  #
515  # foo_switches.cc:
516  #
517  # // A switch.
518  # const char kASwitch = "a-switch";
519  #
520  # FooSwitches.java.tmpl
521  #
522  # // Copyright {YEAR} The Chromium Authors. All rights reserved.
523  # // Use of this source code is governed by a BSD-style license that can be
524  # // found in the LICENSE file.
525  #
526  # // This file is autogenerated by
527  # //     {SCRIPT_NAME}
528  # // From
529  # //     {SOURCE_PATH}, and
530  # //     {TEMPLATE_PATH}
531  #
532  # package my.java.package;
533  #
534  # public abstract class FooSwitches {{
535  #     // ...snip...
536  # {NATIVE_STRINGS}
537  #     // ...snip...
538  # }}
539  #
540  # result:
541  #   A FooSwitches.java file, defining a class named FooSwitches in the package
542  #   my.java.package.
543  template("java_cpp_strings") {
544    action_with_pydeps(target_name) {
545      forward_variables_from(invoker,
546                             [
547                               "sources",
548                               "testonly",
549                               "visibility",
550                             ])
551
552      # The sources aren't compiled so don't check their dependencies.
553      check_includes = false
554      script = "//build/android/gyp/java_cpp_strings.py"
555
556      _srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
557      _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir)
558      _rebased_sources = rebase_path(invoker.sources, root_build_dir)
559      _rebased_template = rebase_path(invoker.template, root_build_dir)
560
561      args = [
562        "--srcjar=$_rebased_srcjar_path",
563        "--template=$_rebased_template",
564      ]
565      args += _rebased_sources
566      sources += [ invoker.template ]
567
568      outputs = [ _srcjar_path ]
569    }
570  }
571
572  # Declare a target for generating Java classes with string constants matching
573  # those found in C++ base::Feature declarations, using a python script.
574  #
575  # This target will create a single .srcjar. Adding this target to an
576  # android_library target's srcjar_deps will make the generated java files be
577  # included in that library's final outputs.
578  #
579  # Variables
580  #   sources: list of files to be processed by the script. For each
581  #            base::Feature in the source files, the script will add a
582  #            corresponding Java string for that feature's name to the
583  #            specified template file.
584  # Example
585  #   java_cpp_features("foo_features") {
586  #     sources = [
587  #       "src/foo_features.cc",
588  #     ]
589  #     template = "src/templates/FooFeatures.java.tmpl
590  #   }
591  #
592  # foo_features.cc:
593  #
594  # // A feature.
595  # const base::Feature kSomeFeature{"SomeFeature",
596  #                                  base::FEATURE_DISABLED_BY_DEFAULT};
597  #
598  # FooFeatures.java.tmpl
599  #
600  # // Copyright $YEAR The Chromium Authors. All rights reserved.
601  # // Use of this source code is governed by a BSD-style license that can be
602  # // found in the LICENSE file.
603  #
604  # package my.java.package;
605  #
606  # public final class FooFeatures {{
607  #     // ...snip...
608  # {NATIVE_STRINGS}
609  #     // ...snip...
610  #     // Do not instantiate this class.
611  #     private FooFeatures() {{}}
612  # }}
613  #
614  # result:
615  #   A FooFeatures.java file, defining a class named FooFeatures in the package
616  #   my.java.package.
617  template("java_cpp_features") {
618    action_with_pydeps(target_name) {
619      forward_variables_from(invoker,
620                             [
621                               "sources",
622                               "testonly",
623                               "visibility",
624                             ])
625
626      # The sources aren't compiled so don't check their dependencies.
627      check_includes = false
628      script = "//build/android/gyp/java_cpp_features.py"
629
630      _srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
631      _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir)
632      _rebased_sources = rebase_path(invoker.sources, root_build_dir)
633      _rebased_template = rebase_path(invoker.template, root_build_dir)
634
635      args = [
636        "--srcjar=$_rebased_srcjar_path",
637        "--template=$_rebased_template",
638      ]
639      args += _rebased_sources
640      sources += [ invoker.template ]
641
642      outputs = [ _srcjar_path ]
643    }
644  }
645
646  # Declare a target for processing a Jinja template.
647  #
648  # Variables
649  #   input: The template file to be processed.
650  #   includes: List of files {% include %}'ed by input.
651  #   output: Where to save the result.
652  #   variables: (Optional) A list of variables to make available to the template
653  #     processing environment, e.g. ["name=foo", "color=red"].
654  #
655  # Example
656  #   jinja_template("chrome_public_manifest") {
657  #     input = "java/AndroidManifest.xml"
658  #     output = "$target_gen_dir/AndroidManifest.xml"
659  #   }
660  template("jinja_template") {
661    action_with_pydeps(target_name) {
662      # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
663      run_under_python2 = true
664
665      forward_variables_from(invoker,
666                             [
667                               "visibility",
668                               "deps",
669                               "testonly",
670                             ])
671      inputs = [ invoker.input ]
672      if (defined(invoker.includes)) {
673        inputs += invoker.includes
674      }
675      script = "//build/android/gyp/jinja_template.py"
676
677      outputs = [ invoker.output ]
678
679      args = [
680        "--loader-base-dir",
681        rebase_path("//", root_build_dir),
682        "--inputs",
683        rebase_path(invoker.input, root_build_dir),
684        "--output",
685        rebase_path(invoker.output, root_build_dir),
686        "--check-includes",
687      ]
688      if (defined(invoker.includes)) {
689        _rebased_includes = rebase_path(invoker.includes, root_build_dir)
690        args += [ "--includes=$_rebased_includes" ]
691      }
692      if (defined(invoker.variables)) {
693        args += [ "--variables=${invoker.variables}" ]
694      }
695    }
696  }
697
698  # Writes native libraries to a NativeLibaries.java file.
699  #
700  # This target will create a single .srcjar. Adding this target to an
701  # android_library target's srcjar_deps will make the generated java files be
702  # included in that library's final outputs.
703  #
704  # Variables:
705  #   native_libraries_list_file: (Optional) Path to file listing all native
706  #     libraries to write.
707  #   version_number: (Optional) String of expected version of 'main' native
708  #     library.
709  #   enable_chromium_linker: (Optional) Whether to use the Chromium linker.
710  #   load_library_from_apk: (Optional) Whether libraries should be loaded from
711  #     the APK without uncompressing.
712  #   use_final_fields: True to use final fields. When false, all other
713  #       variables must not be set.
714  template("write_native_libraries_java") {
715    _native_libraries_file = "$target_gen_dir/$target_name.srcjar"
716    if (current_cpu == "arm" || current_cpu == "arm64") {
717      _cpu_family = "CPU_FAMILY_ARM"
718    } else if (current_cpu == "x86" || current_cpu == "x64") {
719      _cpu_family = "CPU_FAMILY_X86"
720    } else if (current_cpu == "mipsel" || current_cpu == "mips64el") {
721      _cpu_family = "CPU_FAMILY_MIPS"
722    } else {
723      assert(false, "Unsupported CPU family")
724    }
725
726    action_with_pydeps(target_name) {
727      forward_variables_from(invoker,
728                             [
729                               "deps",
730                               "testonly",
731                             ])
732      script = "//build/android/gyp/write_native_libraries_java.py"
733      outputs = [ _native_libraries_file ]
734      args = [
735        "--output",
736        rebase_path(_native_libraries_file, root_build_dir),
737        "--cpu-family",
738        _cpu_family,
739      ]
740      if (invoker.use_final_fields) {
741        # Write native_libraries_list_file via depfile rather than specifyin it
742        # as a dep in order allow R8 to run in parallel with native compilation.
743        depfile = "$target_gen_dir/$target_name.d"
744        args += [
745          "--final",
746          "--depfile",
747          rebase_path(depfile, root_build_dir),
748          "--native-libraries-list",
749          rebase_path(invoker.native_libraries_list_file, root_build_dir),
750        ]
751        if (defined(invoker.version_number)) {
752          args += [
753            "--version-number",
754            invoker.version_number,
755          ]
756        }
757        if (defined(invoker.main_component_library)) {
758          args += [
759            "--main-component-library",
760            invoker.main_component_library,
761          ]
762        }
763        if (defined(invoker.enable_chromium_linker) &&
764            invoker.enable_chromium_linker) {
765          args += [ "--enable-chromium-linker" ]
766        }
767        if (defined(invoker.load_library_from_apk) &&
768            invoker.load_library_from_apk) {
769          args += [ "--load-library-from-apk" ]
770        }
771        if (defined(invoker.use_modern_linker) && invoker.use_modern_linker) {
772          args += [ "--use-modern-linker" ]
773        }
774      }
775    }
776  }
777
778  # Declare a target for a set of Android resources generated at build
779  # time and stored in a single zip archive. The content of the archive
780  # should match the layout of a regular Android res/ folder (but the
781  # archive should not include a top-level res/ directory).
782  #
783  # Note that there is no associated .srcjar, R.txt or package name
784  # associated with this target.
785  #
786  # Variables:
787  #   generated_resources_zip: Generated zip archive path.
788  #   generating_target_name: Name of the target generating
789  #     generated_resources_zip. This rule will check that it is part
790  #     of its outputs.
791  #   deps: Specifies the dependencies of this target. Any Android resources
792  #     listed here will be also be included *after* this one when compiling
793  #     all resources for a final apk or junit binary. This is useful to
794  #     ensure that the resources of the current target override those of the
795  #     dependency as well (and would not work if you have these deps to the
796  #     generating target's dependencies).
797  #
798  # Example
799  #   _zip_archive = "$target_gen_dir/${target_name}.resources_zip"
800  #
801  #   action("my_resources__create_zip") {
802  #     _depfile = "$target_gen_dir/${target_name}.d"
803  #     script = "//build/path/to/create_my_resources_zip.py"
804  #     args = [
805  #       "--depfile", rebase_path(_depfile, root_build_dir),
806  #       "--output-zip", rebase_path(_zip_archive, root_build_dir),
807  #     ]
808  #     inputs = []
809  #     outputs = _zip_archive
810  #     depfile = _depfile
811  #   }
812  #
813  #   android_generated_resources("my_resources") {
814  #      generated_resources_zip = _zip_archive
815  #      generating_target_name = ":my_resources__create_zip"
816  #   }
817  #
818  template("android_generated_resources") {
819    forward_variables_from(invoker, [ "testonly" ])
820
821    _build_config = "$target_gen_dir/${target_name}.build_config"
822
823    write_build_config("$target_name$build_config_target_suffix") {
824      forward_variables_from(invoker, [ "resource_overlay" ])
825
826      build_config = _build_config
827      resources_zip = invoker.generated_resources_zip
828      type = "android_resources"
829      if (defined(invoker.deps)) {
830        possible_config_deps = invoker.deps
831      }
832    }
833
834    group(target_name) {
835      public_deps = [
836        ":$target_name$build_config_target_suffix",
837        invoker.generating_target_name,
838      ]
839    }
840  }
841
842  # Declare a target for processing Android resources as Jinja templates.
843  #
844  # This takes an Android resource directory where each resource is a Jinja
845  # template, processes each template, then packages the results in a zip file
846  # which can be consumed by an android resources, library, or apk target.
847  #
848  # If this target is included in the deps of an android resources/library/apk,
849  # the resources will be included with that target.
850  #
851  # Variables
852  #   resources: The list of resources files to process.
853  #   res_dir: The resource directory containing the resources.
854  #   variables: (Optional) A list of variables to make available to the template
855  #     processing environment, e.g. ["name=foo", "color=red"].
856  #
857  # Example
858  #   jinja_template_resources("chrome_public_template_resources") {
859  #     res_dir = "res_template"
860  #     resources = ["res_template/xml/syncable.xml"]
861  #     variables = ["color=red"]
862  #   }
863  template("jinja_template_resources") {
864    _resources_zip = "$target_out_dir/${target_name}.resources.zip"
865    _generating_target_name = "${target_name}__template"
866
867    action_with_pydeps(_generating_target_name) {
868      # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
869      run_under_python2 = true
870
871      forward_variables_from(invoker,
872                             [
873                               "deps",
874                               "testonly",
875                             ])
876      inputs = invoker.resources
877      script = "//build/android/gyp/jinja_template.py"
878
879      outputs = [ _resources_zip ]
880
881      _rebased_resources = rebase_path(invoker.resources, root_build_dir)
882      args = [
883        "--inputs=${_rebased_resources}",
884        "--inputs-base-dir",
885        rebase_path(invoker.res_dir, root_build_dir),
886        "--outputs-zip",
887        rebase_path(_resources_zip, root_build_dir),
888        "--check-includes",
889      ]
890      if (defined(invoker.variables)) {
891        variables = invoker.variables
892        args += [ "--variables=${variables}" ]
893      }
894    }
895
896    android_generated_resources(target_name) {
897      forward_variables_from(invoker,
898                             [
899                               "deps",
900                               "resource_overlay",
901                               "testonly",
902                             ])
903      generating_target_name = ":$_generating_target_name"
904      generated_resources_zip = _resources_zip
905    }
906  }
907
908  # Declare a prebuilt android native library.
909  #
910  # This takes a base directory and library name and then looks for the library
911  # in <base dir>/$android_app_abi/<library name>.
912  #
913  # If you depend on this target, the library is stripped and output to the
914  # same locations non-prebuilt libraries are output.
915  #
916  # Variables
917  #   base_dir: Directory where all ABIs of the library live.
918  #   library_name: Name of the library .so file.
919  #
920  # Example
921  #   android_native_prebuilt("elements_native") {
922  #     base_dir = "//third_party/elements"
923  #     lib_name = "elements.so"
924  #   }
925  template("android_native_prebuilt") {
926    action_with_pydeps(target_name) {
927      forward_variables_from(invoker,
928                             [
929                               "deps",
930                               "testonly",
931                             ])
932      script = "//build/android/gyp/process_native_prebuilt.py"
933      _lib_path = "${invoker.base_dir}/$android_app_abi/${invoker.lib_name}"
934      _stripped_output_path = "$root_out_dir/${invoker.lib_name}"
935      _unstripped_output_path =
936          "$root_out_dir/lib.unstripped/${invoker.lib_name}"
937      inputs = [ _lib_path ]
938      outputs = [
939        _stripped_output_path,
940        _unstripped_output_path,
941      ]
942
943      # Add unstripped output to runtime deps for use by bots during stacktrace
944      # symbolization.
945      data = [ _unstripped_output_path ]
946
947      _rebased_lib_path = rebase_path(_lib_path, root_build_dir)
948      _rebased_stripped_ouput_path =
949          rebase_path(_stripped_output_path, root_build_dir)
950      _rebased_unstripped_ouput_path =
951          rebase_path(_unstripped_output_path, root_build_dir)
952      _strip_tool_path =
953          rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip",
954                      root_build_dir)
955
956      args = [
957        "--strip-path=$_strip_tool_path",
958        "--input-path=$_rebased_lib_path",
959        "--stripped-output-path=$_rebased_stripped_ouput_path",
960        "--unstripped-output-path=$_rebased_unstripped_ouput_path",
961      ]
962    }
963  }
964
965  # Declare an Android resources target
966  #
967  # This creates a resources zip file that will be used when building an Android
968  # library or apk and included into a final apk.
969  #
970  # To include these resources in a library/apk, this target should be listed in
971  # the library's deps. A library/apk will also include any resources used by its
972  # own dependencies.
973  #
974  # Variables
975  #   sources: List of resource files for this target.
976  #   deps: Specifies the dependencies of this target. Any Android resources
977  #     listed in deps will be included by libraries/apks that depend on this
978  #     target.
979  #   alternative_android_sdk_dep: Optional. Alternative Android system
980  #     android java target to use.
981  #   android_manifest: AndroidManifest.xml for this target (optional). Will be
982  #     merged into apks that directly or indirectly depend on this target.
983  #   android_manifest_dep: Target that generates AndroidManifest (if applicable)
984  #   custom_package: java package for generated .java files.
985  #   shared_resources: If true make a resource package that can be loaded by a
986  #     different application at runtime to access the package's resources.
987  #   resource_overlay: Whether the resources in 'sources' should override
988  #     resources with the same name. Does not affect the behaviour of any
989  #     android_resources() deps of this target. If a target with
990  #     resource_overlay=true depends on another target with
991  #     resource_overlay=true the target with the dependency overrides the
992  #     other.
993  #   r_text_file: (optional) path to pre-generated R.txt to be used when
994  #     generating R.java instead of resource-based aapt-generated one.
995  #   recursive_resource_deps: (optional) whether deps should be walked
996  #     recursively to find resource deps.
997  #
998  # Example:
999  #   android_resources("foo_resources") {
1000  #     deps = [":foo_strings_grd"]
1001  #     sources = [
1002  #       "res/drawable/foo1.xml",
1003  #       "res/drawable/foo2.xml",
1004  #     ]
1005  #     custom_package = "org.chromium.foo"
1006  #   }
1007  #
1008  #   android_resources("foo_resources_overrides") {
1009  #     deps = [":foo_resources"]
1010  #     sources = [
1011  #       "res_overrides/drawable/foo1.xml",
1012  #       "res_overrides/drawable/foo2.xml",
1013  #     ]
1014  #   }
1015  template("android_resources") {
1016    forward_variables_from(invoker, [ "testonly" ])
1017
1018    _base_path = "$target_gen_dir/$target_name"
1019    if (defined(invoker.v14_skip)) {
1020      not_needed(invoker, [ "v14_skip" ])
1021    }
1022
1023    assert(!defined(invoker.resource_dirs) || defined(invoker.sources),
1024           "resource_dirs in android_resources is deprecated. Please use " +
1025               "sources=[] and list resource files instead. Details: " +
1026               "https://crbug.com/1026378")
1027    _res_sources_path = "$target_gen_dir/${invoker.target_name}.res.sources"
1028
1029    _resources_zip = "$target_out_dir/$target_name.resources.zip"
1030    _r_text_out_path = _base_path + "_R.txt"
1031    _build_config = _base_path + ".build_config"
1032    _build_config_target_name = "$target_name$build_config_target_suffix"
1033
1034    if (defined(invoker.create_srcjar)) {
1035      assert(!invoker.create_srcjar,
1036             "create_srcjar=true has been deprecated. " +
1037                 "See https://crbug.com/1073476")
1038    }
1039
1040    _deps = []
1041    if (defined(invoker.deps)) {
1042      _deps += invoker.deps
1043    }
1044
1045    if (defined(invoker.alternative_android_sdk_dep)) {
1046      _deps += [ invoker.alternative_android_sdk_dep ]
1047    } else {
1048      _deps += [ "//third_party/android_sdk:android_sdk_java" ]
1049    }
1050
1051    _resource_files = []
1052    if (defined(invoker.sources)) {
1053      _resource_files += invoker.sources
1054    }
1055
1056    _rebased_resource_files = rebase_path(_resource_files, root_build_dir)
1057    write_file(_res_sources_path, _rebased_resource_files)
1058
1059    # This is necessary so we only lint chromium resources.
1060    if (defined(invoker.chromium_code)) {
1061      _chromium_code = invoker.chromium_code
1062    } else {
1063      # Default based on whether target is in third_party.
1064      _chromium_code =
1065          filter_exclude([ get_label_info(":$target_name", "dir") ],
1066                         [ "*\bthird_party\b*" ]) != []
1067    }
1068
1069    write_build_config(_build_config_target_name) {
1070      type = "android_resources"
1071      build_config = _build_config
1072      resources_zip = _resources_zip
1073      res_sources_path = _res_sources_path
1074      chromium_code = _chromium_code
1075
1076      forward_variables_from(invoker,
1077                             [
1078                               "android_manifest",
1079                               "android_manifest_dep",
1080                               "custom_package",
1081                               "mergeable_android_manifests",
1082                               "resource_overlay",
1083                               "recursive_resource_deps",
1084                             ])
1085
1086      # No package means resources override their deps.
1087      if (defined(custom_package) || defined(android_manifest)) {
1088        r_text = _r_text_out_path
1089      }
1090
1091      possible_config_deps = _deps
1092
1093      # Always merge manifests from resources.
1094      # * Might want to change this at some point for consistency and clarity,
1095      #   but keeping for backwards-compatibility.
1096      if (!defined(mergeable_android_manifests) && defined(android_manifest)) {
1097        mergeable_android_manifests = [ android_manifest ]
1098      }
1099    }
1100
1101    prepare_resources(target_name) {
1102      forward_variables_from(invoker,
1103                             [
1104                               "android_manifest",
1105                               "custom_package",
1106                               "strip_drawables",
1107                             ])
1108      deps = _deps
1109      deps += [ ":$_build_config_target_name" ]
1110      if (defined(invoker.android_manifest_dep)) {
1111        deps += [ invoker.android_manifest_dep ]
1112      }
1113
1114      res_sources_path = _res_sources_path
1115      sources = _resource_files
1116
1117      build_config = _build_config
1118      resources_zip = _resources_zip
1119      r_text_out_path = _r_text_out_path
1120
1121      if (defined(invoker.r_text_file)) {
1122        r_text_in_path = invoker.r_text_file
1123      }
1124
1125      # Always generate R.onResourcesLoaded() method, it is required for
1126      # compiling ResourceRewriter, there is no side effect because the
1127      # generated R.class isn't used in final apk.
1128      shared_resources = true
1129    }
1130  }
1131
1132  # Declare an Android assets target.
1133  #
1134  # Defines a set of files to include as assets in a dependent apk.
1135  #
1136  # To include these assets in an apk, this target should be listed in
1137  # the apk's deps, or in the deps of a library target used by an apk.
1138  #
1139  # Variables
1140  #   deps: Specifies the dependencies of this target. Any Android assets
1141  #     listed in deps will be included by libraries/apks that depend on this
1142  #     target.
1143  #   sources: List of files to include as assets.
1144  #   renaming_sources: List of files to include as assets and be renamed.
1145  #   renaming_destinations: List of asset paths for files in renaming_sources.
1146  #   disable_compression: Whether to disable compression for files that are
1147  #     known to be compressable (default: false).
1148  #   treat_as_locale_paks: Causes base's BuildConfig.java to consider these
1149  #     assets to be locale paks.
1150  #
1151  # Example:
1152  # android_assets("content_shell_assets") {
1153  #   deps = [
1154  #     ":generates_foo",
1155  #     ":other_assets",
1156  #     ]
1157  #   sources = [
1158  #     "//path/asset1.png",
1159  #     "//path/asset2.png",
1160  #     "$target_gen_dir/foo.dat",
1161  #   ]
1162  # }
1163  #
1164  # android_assets("overriding_content_shell_assets") {
1165  #   deps = [ ":content_shell_assets" ]
1166  #   # Override foo.dat from content_shell_assets.
1167  #   sources = [ "//custom/foo.dat" ]
1168  #   renaming_sources = [ "//path/asset2.png" ]
1169  #   renaming_destinations = [ "renamed/asset2.png" ]
1170  # }
1171  template("android_assets") {
1172    forward_variables_from(invoker, [ "testonly" ])
1173
1174    _build_config = "$target_gen_dir/$target_name.build_config"
1175    _build_config_target_name = "$target_name$build_config_target_suffix"
1176
1177    write_build_config(_build_config_target_name) {
1178      type = "android_assets"
1179      build_config = _build_config
1180
1181      forward_variables_from(invoker,
1182                             [
1183                               "disable_compression",
1184                               "treat_as_locale_paks",
1185                             ])
1186
1187      if (defined(invoker.deps)) {
1188        possible_config_deps = invoker.deps
1189      }
1190
1191      if (defined(invoker.sources)) {
1192        asset_sources = invoker.sources
1193      }
1194      if (defined(invoker.renaming_sources)) {
1195        assert(defined(invoker.renaming_destinations))
1196        _source_count = 0
1197        foreach(_, invoker.renaming_sources) {
1198          _source_count += 1
1199        }
1200        _dest_count = 0
1201        foreach(_, invoker.renaming_destinations) {
1202          _dest_count += 1
1203        }
1204        assert(
1205            _source_count == _dest_count,
1206            "android_assets() renaming_sources.length != renaming_destinations.length")
1207        asset_renaming_sources = invoker.renaming_sources
1208        asset_renaming_destinations = invoker.renaming_destinations
1209      }
1210    }
1211
1212    group(target_name) {
1213      forward_variables_from(invoker,
1214                             [
1215                               "deps",
1216                               "visibility",
1217                             ])
1218      public_deps = [ ":$_build_config_target_name" ]
1219    }
1220  }
1221
1222  # Declare a group() that supports forwarding java dependency information.
1223  #
1224  # Example
1225  #  java_group("conditional_deps") {
1226  #    if (enable_foo) {
1227  #      deps = [":foo_java"]
1228  #    }
1229  #  }
1230  template("java_group") {
1231    _build_config_vars = [
1232      "input_jars_paths",
1233      "mergeable_android_manifests",
1234      "proguard_configs",
1235    ]
1236    forward_variables_from(invoker, [ "testonly" ])
1237    write_build_config("$target_name$build_config_target_suffix") {
1238      forward_variables_from(invoker, _build_config_vars)
1239      type = "group"
1240      build_config = "$target_gen_dir/${invoker.target_name}.build_config"
1241      supports_android = true
1242      if (defined(invoker.deps)) {
1243        possible_config_deps = invoker.deps
1244      }
1245    }
1246    foreach(_group_name,
1247            [
1248              "header",
1249              "impl",
1250              "assetres",
1251            ]) {
1252      java_lib_group("${target_name}__${_group_name}") {
1253        forward_variables_from(invoker, [ "deps" ])
1254        group_name = _group_name
1255      }
1256    }
1257    group(target_name) {
1258      forward_variables_from(invoker, "*", _build_config_vars)
1259      if (!defined(deps)) {
1260        deps = []
1261      }
1262      deps += [ ":$target_name$build_config_target_suffix" ]
1263    }
1264  }
1265
1266  # Declare a Java executable target
1267  #
1268  # Same as java_library, but also creates a wrapper script within
1269  # $root_out_dir/bin.
1270  #
1271  # Supports all variables of java_library(), plus:
1272  #   main_class: When specified, a wrapper script is created within
1273  #     $root_build_dir/bin to launch the binary with the given class as the
1274  #     entrypoint.
1275  #   wrapper_script_name: Filename for the wrapper script (default=target_name)
1276  #   wrapper_script_args: List of additional arguments for the wrapper script.
1277  #
1278  # Example
1279  #   java_binary("foo") {
1280  #     sources = [ "org/chromium/foo/FooMain.java" ]
1281  #     deps = [ ":bar_java" ]
1282  #     main_class = "org.chromium.foo.FooMain"
1283  #   }
1284  #
1285  #   java_binary("foo") {
1286  #     jar_path = "lib/prebuilt.jar"
1287  #     deps = [ ":bar_java" ]
1288  #     main_class = "org.chromium.foo.FooMain"
1289  #   }
1290  template("java_binary") {
1291    java_library_impl(target_name) {
1292      forward_variables_from(invoker, "*")
1293      type = "java_binary"
1294      if (!defined(data_deps)) {
1295        data_deps = []
1296      }
1297      data_deps += [ "//third_party/jdk:java_data" ]
1298    }
1299  }
1300
1301  # Declare a Java Annotation Processor.
1302  #
1303  # Supports all variables of java_library(), plus:
1304  #   jar_path: Path to a prebuilt jar. Mutually exclusive with sources &
1305  #     srcjar_deps.
1306  #   main_class: The fully-quallified class name of the processor's entry
1307  #       point.
1308  #
1309  # Example
1310  #   java_annotation_processor("foo_processor") {
1311  #     sources = [ "org/chromium/foo/FooProcessor.java" ]
1312  #     deps = [ ":bar_java" ]
1313  #     main_class = "org.chromium.foo.FooProcessor"
1314  #   }
1315  #
1316  #   java_annotation_processor("foo_processor") {
1317  #     jar_path = "lib/prebuilt.jar"
1318  #     main_class = "org.chromium.foo.FooMain"
1319  #   }
1320  #
1321  #   java_library("...") {
1322  #     annotation_processor_deps = [":foo_processor"]
1323  #   }
1324  #
1325  template("java_annotation_processor") {
1326    java_library_impl(target_name) {
1327      forward_variables_from(invoker, "*")
1328      type = "java_annotation_processor"
1329    }
1330  }
1331
1332  # Declare a Junit executable target
1333  #
1334  # This target creates an executable from java code for running as a junit test
1335  # suite. The executable will be in the output folder's /bin/ directory.
1336  #
1337  # Supports all variables of java_binary().
1338  #
1339  # Example
1340  #   junit_binary("foo") {
1341  #     sources = [ "org/chromium/foo/FooTest.java" ]
1342  #     deps = [ ":bar_java" ]
1343  #   }
1344  template("junit_binary") {
1345    testonly = true
1346
1347    _java_binary_target_name = "${target_name}__java_binary"
1348    _test_runner_target_name = "${target_name}__test_runner_script"
1349    _main_class = "org.chromium.testing.local.JunitTestMain"
1350
1351    _build_config = "$target_gen_dir/$target_name.build_config"
1352    _build_config_target_name = "$target_name$build_config_target_suffix"
1353    _deps = [
1354      "//testing/android/junit:junit_test_support",
1355      "//third_party/android_deps:robolectric_all_java",
1356      "//third_party/junit",
1357      "//third_party/mockito:mockito_java",
1358    ]
1359    if (defined(invoker.deps)) {
1360      _deps += invoker.deps
1361    }
1362    if (defined(invoker.alternative_android_sdk_dep)) {
1363      _android_sdk_dep = invoker.alternative_android_sdk_dep
1364    } else {
1365      _android_sdk_dep = "//third_party/android_sdk:android_sdk_java"
1366    }
1367
1368    # a package name or a manifest is required to have resources. This is
1369    # added so that junit tests that do not care about the package name can
1370    # still use resources without having to explicitly set one.
1371    if (defined(invoker.package_name)) {
1372      _package_name = invoker.package_name
1373    } else if (!defined(invoker.android_manifest)) {
1374      _package_name = "org.chromium.test"
1375    }
1376
1377    _resource_arsc_output = "${target_gen_dir}/${target_name}.ap_"
1378    _compile_resources_target = "${target_name}__compile_resources"
1379    compile_resources(_compile_resources_target) {
1380      forward_variables_from(invoker, [ "android_manifest" ])
1381      deps = _deps
1382      android_sdk_dep = _android_sdk_dep
1383      build_config_dep = ":$_build_config_target_name"
1384      build_config = _build_config
1385      if (defined(_package_name)) {
1386        rename_manifest_package = _package_name
1387      }
1388      if (!defined(android_manifest)) {
1389        android_manifest = "//build/android/AndroidManifest.xml"
1390      }
1391      arsc_output = _resource_arsc_output
1392      min_sdk_version = default_min_sdk_version
1393      target_sdk_version = android_sdk_version
1394    }
1395
1396    _jni_srcjar_target = "${target_name}__final_jni"
1397    _outer_target_name = target_name
1398    generate_jni_registration(_jni_srcjar_target) {
1399      enable_native_mocks = true
1400      require_native_mocks = true
1401      targets = [ ":$_outer_target_name" ]
1402    }
1403
1404    java_library_impl(_java_binary_target_name) {
1405      forward_variables_from(invoker, "*", [ "deps" ])
1406      type = "junit_binary"
1407      main_target_name = invoker.target_name
1408
1409      # Include the android SDK jar(s) for resource processing.
1410      include_android_sdk = true
1411
1412      # Robolectric can handle deps that set !supports_android as well those
1413      # that set requires_android.
1414      bypass_platform_checks = true
1415      deps = _deps
1416      testonly = true
1417      main_class = _main_class
1418      wrapper_script_name = "helper/$main_target_name"
1419      if (!defined(srcjar_deps)) {
1420        srcjar_deps = []
1421      }
1422      srcjar_deps += [
1423        ":$_compile_resources_target",
1424        ":$_jni_srcjar_target",
1425
1426        # This dep is required for any targets that depend on //base:base_java.
1427        "//base:base_build_config_gen",
1428      ]
1429    }
1430
1431    test_runner_script(_test_runner_target_name) {
1432      test_name = invoker.target_name
1433      test_suite = invoker.target_name
1434      test_type = "junit"
1435      ignore_all_data_deps = true
1436      resource_apk = _resource_arsc_output
1437    }
1438
1439    group(target_name) {
1440      forward_variables_from(invoker, [ "assert_no_deps" ])
1441      public_deps = [
1442        ":$_build_config_target_name",
1443        ":$_java_binary_target_name",
1444        ":$_test_runner_target_name",
1445      ]
1446    }
1447  }
1448
1449  # Declare a java library target
1450  #
1451  # Variables
1452  #   deps: Specifies the dependencies of this target. Java targets in this list
1453  #     will be added to the javac classpath.
1454  #   annotation_processor_deps: List of java_annotation_processor targets to
1455  #     use when compiling.
1456  #
1457  #   jar_path: Path to a prebuilt jar. Mutually exclusive with sources &
1458  #     srcjar_deps.
1459  #   sources: List of .java files included in this library.
1460  #   srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
1461  #     will be added to sources and be included in this library.
1462  #
1463  #   input_jars_paths: A list of paths to the jars that should be included
1464  #     in the compile-time classpath. These are in addition to library .jars
1465  #     that appear in deps.
1466  #
1467  #   chromium_code: If true, extra analysis warning/errors will be enabled.
1468  #   enable_errorprone: If true, enables the errorprone compiler.
1469  #
1470  #   jar_excluded_patterns: List of patterns of .class files to exclude.
1471  #   jar_included_patterns: List of patterns of .class files to include.
1472  #     When omitted, all classes not matched by jar_excluded_patterns are
1473  #     included. When specified, all non-matching .class files are stripped.
1474  #
1475  #   output_name: File name for the output .jar (not including extension).
1476  #     Defaults to the input .jar file name.
1477  #
1478  #   proguard_configs: List of proguard configs to use in final apk step for
1479  #     any apk that depends on this library.
1480  #
1481  #   supports_android: If true, Android targets (android_library, android_apk)
1482  #     may depend on this target. Note: if true, this target must only use the
1483  #     subset of Java available on Android.
1484  #   bypass_platform_checks: Disables checks about cross-platform (Java/Android)
1485  #     dependencies for this target. This will allow depending on an
1486  #     android_library target, for example.
1487  #   enable_desugar: If false, disables desugaring of lambdas, etc. Use this
1488  #     only when you are sure the library does not require desugaring. E.g.
1489  #     to hide warnings shown from desugaring.
1490  #
1491  #   additional_jar_files: Use to package additional files (Java resources)
1492  #     into the output jar. Pass a list of length-2 lists with format:
1493  #         [ [ path_to_file, path_to_put_in_jar ] ]
1494  #
1495  #   javac_args: Additional arguments to pass to javac.
1496  #   errorprone_args: Additional arguments to pass to errorprone.
1497  #   errorprone_expected_warning_regex: When set, throws an exception if the
1498  #     errorprone compile does not log a warning which matches the regex.
1499  #
1500  #   data_deps, testonly
1501  #
1502  # Example
1503  #   java_library("foo_java") {
1504  #     sources = [
1505  #       "org/chromium/foo/Foo.java",
1506  #       "org/chromium/foo/FooInterface.java",
1507  #       "org/chromium/foo/FooService.java",
1508  #     ]
1509  #     deps = [
1510  #       ":bar_java"
1511  #     ]
1512  #     srcjar_deps = [
1513  #       ":foo_generated_enum"
1514  #     ]
1515  #     jar_excluded_patterns = [
1516  #       "*/FooService.class", "org/chromium/FooService\$*.class"
1517  #     ]
1518  #   }
1519  template("java_library") {
1520    java_library_impl(target_name) {
1521      forward_variables_from(invoker, "*")
1522      type = "java_library"
1523    }
1524  }
1525
1526  # Declare a java library target for a prebuilt jar
1527  #
1528  # Supports all variables of java_library().
1529  #
1530  # Example
1531  #   java_prebuilt("foo_java") {
1532  #     jar_path = "foo.jar"
1533  #     deps = [
1534  #       ":foo_resources",
1535  #       ":bar_java"
1536  #     ]
1537  #   }
1538  template("java_prebuilt") {
1539    java_library_impl(target_name) {
1540      forward_variables_from(invoker, "*")
1541      type = "java_library"
1542    }
1543  }
1544
1545  # Combines all dependent .jar files into a single .jar file.
1546  #
1547  # Variables:
1548  #   output: Path to the output jar.
1549  #   override_build_config: Use a pre-existing .build_config. Must be of type
1550  #     "apk".
1551  #   use_interface_jars: Use all dependent interface .jars rather than
1552  #     implementation .jars.
1553  #   use_unprocessed_jars: Use unprocessed / undesugared .jars.
1554  #   direct_deps_only: Do not recurse on deps.
1555  #   jar_excluded_patterns (optional)
1556  #     List of globs for paths to exclude.
1557  #
1558  # Example
1559  #   dist_jar("lib_fatjar") {
1560  #     deps = [ ":my_java_lib" ]
1561  #     output = "$root_build_dir/MyLibrary.jar"
1562  #   }
1563  template("dist_jar") {
1564    # TODO(crbug.com/1042017): Remove.
1565    not_needed(invoker, [ "no_build_hooks" ])
1566    forward_variables_from(invoker, [ "testonly" ])
1567    _supports_android =
1568        !defined(invoker.supports_android) || invoker.supports_android
1569    _use_interface_jars =
1570        defined(invoker.use_interface_jars) && invoker.use_interface_jars
1571    _use_unprocessed_jars =
1572        defined(invoker.use_unprocessed_jars) && invoker.use_unprocessed_jars
1573    _direct_deps_only =
1574        defined(invoker.direct_deps_only) && invoker.direct_deps_only
1575    assert(!(_use_unprocessed_jars && _use_interface_jars),
1576           "Cannot set both use_interface_jars and use_unprocessed_jars")
1577
1578    _jar_target_name = target_name
1579
1580    _deps = []
1581    if (defined(invoker.deps)) {
1582      _deps = invoker.deps
1583    }
1584    if (_supports_android) {
1585      _deps += [ "//third_party/android_sdk:android_sdk_java" ]
1586    }
1587
1588    if (defined(invoker.override_build_config)) {
1589      _build_config = invoker.override_build_config
1590    } else {
1591      _build_config = "$target_gen_dir/$target_name.build_config"
1592      _build_config_target_name = "$target_name$build_config_target_suffix"
1593
1594      write_build_config(_build_config_target_name) {
1595        type = "dist_jar"
1596        supports_android = _supports_android
1597        requires_android =
1598            defined(invoker.requires_android) && invoker.requires_android
1599        possible_config_deps = _deps
1600        build_config = _build_config
1601      }
1602
1603      _deps += [ ":$_build_config_target_name" ]
1604    }
1605
1606    _rebased_build_config = rebase_path(_build_config, root_build_dir)
1607    action_with_pydeps(_jar_target_name) {
1608      forward_variables_from(invoker, [ "data" ])
1609      script = "//build/android/gyp/zip.py"
1610      depfile = "$target_gen_dir/$target_name.d"
1611      deps = _deps
1612
1613      inputs = [ _build_config ]
1614
1615      outputs = [ invoker.output ]
1616
1617      args = [
1618        "--depfile",
1619        rebase_path(depfile, root_build_dir),
1620        "--output",
1621        rebase_path(invoker.output, root_build_dir),
1622        "--no-compress",
1623      ]
1624
1625      if (_direct_deps_only) {
1626        if (_use_interface_jars) {
1627          args += [ "--input-zips=@FileArg($_rebased_build_config:javac:interface_classpath)" ]
1628        } else if (_use_unprocessed_jars) {
1629          args += [
1630            "--input-zips=@FileArg($_rebased_build_config:javac:classpath)",
1631          ]
1632        } else {
1633          assert(
1634              false,
1635              "direct_deps_only does not work without use_interface_jars or use_unprocessed_jars")
1636        }
1637      } else {
1638        if (_use_interface_jars) {
1639          args += [ "--input-zips=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ]
1640        } else if (_use_unprocessed_jars) {
1641          args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ]
1642        } else {
1643          args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:device_classpath)" ]
1644        }
1645      }
1646      _excludes = []
1647      if (defined(invoker.jar_excluded_patterns)) {
1648        _excludes += invoker.jar_excluded_patterns
1649      }
1650      if (_use_interface_jars) {
1651        # Turbine adds files like: META-INF/TRANSITIVE/.../Foo.class
1652        # These confuse proguard: https://crbug.com/1081443
1653        _excludes += [ "META-INF/*" ]
1654      }
1655      if (_excludes != []) {
1656        args += [ "--input-zips-excluded-globs=$_excludes" ]
1657      }
1658    }
1659  }
1660
1661  # Combines all dependent .jar files into a single proguarded .dex file.
1662  #
1663  # Variables:
1664  #   output: Path to the output dex.
1665  #   proguard_enabled: Whether to enable R8.
1666  #   proguard_configs: List of proguard configs.
1667  #
1668  # Example
1669  #   dist_dex("lib_fatjar") {
1670  #     deps = [ ":my_java_lib" ]
1671  #     output = "$root_build_dir/MyLibrary.jar"
1672  #   }
1673  template("dist_dex") {
1674    _deps = [ "//third_party/android_sdk:android_sdk_java" ]
1675    if (defined(invoker.deps)) {
1676      _deps += invoker.deps
1677    }
1678
1679    _build_config = "$target_gen_dir/$target_name.build_config"
1680    _build_config_target_name = "$target_name$build_config_target_suffix"
1681
1682    write_build_config(_build_config_target_name) {
1683      type = "dist_jar"
1684      forward_variables_from(invoker,
1685                             [
1686                               "proguard_configs",
1687                               "proguard_enabled",
1688                             ])
1689      supports_android = true
1690      requires_android = true
1691      possible_config_deps = _deps
1692      build_config = _build_config
1693    }
1694
1695    _deps += [ ":$_build_config_target_name" ]
1696
1697    dex(target_name) {
1698      forward_variables_from(invoker,
1699                             [
1700                               "data",
1701                               "data_deps",
1702                               "visibility",
1703                               "testonly",
1704                               "proguard_configs",
1705                               "proguard_enabled",
1706                               "min_sdk_version",
1707                             ])
1708      deps = _deps
1709      build_config = _build_config
1710      enable_multidex = false
1711      output = invoker.output
1712      if (defined(proguard_enabled) && proguard_enabled) {
1713        # When trying to build a stand-alone .dex, don't add in jdk_libs_dex.
1714        supports_jdk_library_desugaring = false
1715      } else {
1716        _rebased_build_config = rebase_path(_build_config, root_build_dir)
1717        input_dex_filearg =
1718            "@FileArg(${_rebased_build_config}:final_dex:all_dex_files)"
1719      }
1720    }
1721  }
1722
1723  # Creates an Android .aar library.
1724  #
1725  # Currently supports:
1726  #   * AndroidManifest.xml
1727  #   * classes.jar
1728  #   * jni/
1729  #   * res/
1730  #   * R.txt
1731  #   * proguard.txt
1732  # Does not yet support:
1733  #   * public.txt
1734  #   * annotations.zip
1735  #   * assets/
1736  # See: https://developer.android.com/studio/projects/android-library.html#aar-contents
1737  #
1738  # Variables:
1739  #   output: Path to the output .aar.
1740  #   proguard_configs: List of proguard configs (optional).
1741  #   android_manifest: Path to AndroidManifest.xml (optional).
1742  #   native_libraries: list of native libraries (optional).
1743  #   direct_deps_only: Do not recurse on deps. (optional, defaults false).
1744  #   jar_excluded_patterns (optional): List of globs for paths to exclude.
1745  #   jar_included_patterns (optional): List of globs for paths to include.
1746  #
1747  # Example
1748  #   dist_aar("my_aar") {
1749  #     deps = [ ":my_java_lib" ]
1750  #     output = "$root_build_dir/MyLibrary.aar"
1751  #   }
1752  template("dist_aar") {
1753    forward_variables_from(invoker, [ "testonly" ])
1754
1755    _deps = []
1756    if (defined(invoker.deps)) {
1757      _deps = invoker.deps
1758    }
1759
1760    _direct_deps_only =
1761        defined(invoker.direct_deps_only) && invoker.direct_deps_only
1762
1763    _build_config = "$target_gen_dir/$target_name.build_config"
1764    _build_config_target_name = "$target_name$build_config_target_suffix"
1765
1766    write_build_config(_build_config_target_name) {
1767      type = "dist_aar"
1768      forward_variables_from(invoker, [ "proguard_configs" ])
1769      possible_config_deps = _deps
1770      supports_android = true
1771      requires_android = true
1772      build_config = _build_config
1773    }
1774
1775    _deps += [ ":$_build_config_target_name" ]
1776
1777    _rebased_build_config = rebase_path(_build_config, root_build_dir)
1778
1779    action_with_pydeps(target_name) {
1780      forward_variables_from(invoker, [ "data" ])
1781      depfile = "$target_gen_dir/$target_name.d"
1782      deps = _deps
1783      script = "//build/android/gyp/dist_aar.py"
1784
1785      inputs = [ _build_config ]
1786
1787      # Although these will be listed as deps in the depfile, they must also
1788      # appear here so that "gn analyze" knows about them.
1789      # https://crbug.com/827197
1790      if (defined(invoker.proguard_configs)) {
1791        inputs += invoker.proguard_configs
1792      }
1793
1794      outputs = [ invoker.output ]
1795
1796      args = [
1797        "--depfile",
1798        rebase_path(depfile, root_build_dir),
1799        "--output",
1800        rebase_path(invoker.output, root_build_dir),
1801        "--dependencies-res-zips=@FileArg($_rebased_build_config:deps_info:dependency_zips)",
1802        "--r-text-files=@FileArg($_rebased_build_config:deps_info:dependency_r_txt_files)",
1803        "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)",
1804      ]
1805      if (_direct_deps_only) {
1806        args += [ "--jars=@FileArg($_rebased_build_config:javac:classpath)" ]
1807      } else {
1808        args += [ "--jars=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ]
1809      }
1810      if (defined(invoker.android_manifest)) {
1811        args += [
1812          "--android-manifest",
1813          rebase_path(invoker.android_manifest, root_build_dir),
1814        ]
1815      }
1816      if (defined(invoker.native_libraries) && invoker.native_libraries != []) {
1817        inputs += invoker.native_libraries
1818        _rebased_native_libraries =
1819            rebase_path(invoker.native_libraries, root_build_dir)
1820
1821        args += [
1822          "--native-libraries=$_rebased_native_libraries",
1823          "--abi=$android_app_abi",
1824        ]
1825      }
1826      if (defined(invoker.jar_excluded_patterns)) {
1827        args += [ "--jar-excluded-globs=${invoker.jar_excluded_patterns}" ]
1828      }
1829      if (defined(invoker.jar_included_patterns)) {
1830        args += [ "--jar-included-globs=${invoker.jar_included_patterns}" ]
1831      }
1832      if (defined(invoker.resource_included_patterns)) {
1833        args += [
1834          "--resource-included-globs=${invoker.resource_included_patterns}",
1835        ]
1836      }
1837    }
1838  }
1839
1840  # Declare an Android library target
1841  #
1842  # This target creates an Android library containing java code and Android
1843  # resources.
1844  #
1845  # Supports all variables of java_library(), plus:
1846  #   deps: In addition to defining java deps, this can also include
1847  #     android_assets() and android_resources() targets.
1848  #   alternative_android_sdk_ijar: if set, the given android_sdk_ijar file
1849  #     replaces the default android_sdk_ijar.
1850  #   alternative_android_sdk_ijar_dep: the target that generates
1851  #      alternative_android_sdk_ijar, must be set if alternative_android_sdk_ijar
1852  #      is used.
1853  #   alternative_android_sdk_jar: actual jar corresponding to
1854  #      alternative_android_sdk_ijar, must be set if alternative_android_sdk_ijar
1855  #      is used.
1856  #
1857  # Example
1858  #   android_library("foo_java") {
1859  #     sources = [
1860  #       "android/org/chromium/foo/Foo.java",
1861  #       "android/org/chromium/foo/FooInterface.java",
1862  #       "android/org/chromium/foo/FooService.java",
1863  #     ]
1864  #     deps = [
1865  #       ":bar_java"
1866  #     ]
1867  #     srcjar_deps = [
1868  #       ":foo_generated_enum"
1869  #     ]
1870  #     jar_excluded_patterns = [
1871  #       "*/FooService.class", "org/chromium/FooService\$*.class"
1872  #     ]
1873  #   }
1874  template("android_library") {
1875    java_library(target_name) {
1876      forward_variables_from(invoker, "*")
1877
1878      supports_android = true
1879      requires_android = true
1880
1881      if (!defined(jar_excluded_patterns)) {
1882        jar_excluded_patterns = []
1883      }
1884      jar_excluded_patterns += [
1885        "*/R.class",
1886        "*/R\$*.class",
1887        "*/Manifest.class",
1888        "*/Manifest\$*.class",
1889        "*/GEN_JNI.class",
1890      ]
1891    }
1892  }
1893
1894  # Declare an Android library target for a prebuilt jar
1895  #
1896  # This target creates an Android library containing java code and Android
1897  # resources.
1898  #
1899  # Supports all variables of android_library().
1900  #
1901  # Example
1902  #   android_java_prebuilt("foo_java") {
1903  #     jar_path = "foo.jar"
1904  #     deps = [
1905  #       ":foo_resources",
1906  #       ":bar_java"
1907  #     ]
1908  #   }
1909  template("android_java_prebuilt") {
1910    android_library(target_name) {
1911      forward_variables_from(invoker, "*")
1912    }
1913  }
1914
1915  template("android_system_java_prebuilt") {
1916    java_library_impl(target_name) {
1917      forward_variables_from(invoker, "*")
1918      supports_android = true
1919      type = "system_java_library"
1920    }
1921  }
1922
1923  # Creates org/chromium/base/BuildConfig.java
1924  # This doesn't really belong in //build since it genates a file for //base.
1925  # However, we don't currently have a better way to include this file in all
1926  # apks that depend on //base:base_java.
1927  #
1928  # Variables:
1929  #   use_final_fields: True to use final fields. When false, all other
1930  #       variables must not be set.
1931  #   enable_multidex: Value for ENABLE_MULTIDEX.
1932  #   min_sdk_version: Value for MIN_SDK_VERSION.
1933  #   bundles_supported: Whether or not this target can be treated as a bundle.
1934  #   resources_version_variable:
1935  #   is_incremental_install:
1936  #   isolated_splits_enabled: Value for ISOLATED_SPLITS_ENABLED.
1937  template("generate_build_config_srcjar") {
1938    java_cpp_template(target_name) {
1939      sources = [ "//base/android/java/templates/BuildConfig.template" ]
1940      defines = []
1941
1942      # Set these even when !use_final_fields so that they have correct default
1943      # values within junit_binary(), which ignores jar_excluded_patterns.
1944      if (is_java_debug || dcheck_always_on) {
1945        defines += [ "_DCHECK_IS_ON" ]
1946      }
1947      if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) {
1948        defines += [ "_IS_UBSAN" ]
1949      }
1950
1951      if (is_chrome_branded) {
1952        defines += [ "_IS_CHROME_BRANDED" ]
1953      }
1954
1955      if (is_chromecast && chromecast_branding == "internal") {
1956        defines += [ "_IS_CHROMECAST_BRANDING_INTERNAL" ]
1957      }
1958
1959      if (defined(invoker.bundles_supported) && invoker.bundles_supported) {
1960        defines += [ "_BUNDLES_SUPPORTED" ]
1961      }
1962
1963      if (defined(invoker.isolated_splits_enabled) &&
1964          invoker.isolated_splits_enabled) {
1965        defines += [ "_ISOLATED_SPLITS_ENABLED" ]
1966      }
1967
1968      if (defined(invoker.is_incremental_install) &&
1969          invoker.is_incremental_install) {
1970        defines += [ "_IS_INCREMENTAL_INSTALL" ]
1971      }
1972
1973      if (invoker.use_final_fields) {
1974        forward_variables_from(invoker,
1975                               [
1976                                 "deps",
1977                                 "testonly",
1978                               ])
1979        defines += [ "USE_FINAL" ]
1980        if (invoker.enable_multidex) {
1981          defines += [ "ENABLE_MULTIDEX" ]
1982        }
1983        if (defined(invoker.min_sdk_version)) {
1984          defines += [ "_MIN_SDK_VERSION=${invoker.min_sdk_version}" ]
1985        }
1986        if (defined(invoker.resources_version_variable)) {
1987          defines += [
1988            "_RESOURCES_VERSION_VARIABLE=${invoker.resources_version_variable}",
1989          ]
1990        }
1991      }
1992    }
1993  }
1994
1995  # Creates ProductConfig.java, a file containing product-specific configuration.
1996  #
1997  # Currently, this includes the list of locales, both in their compressed and
1998  # uncompressed format, as well as library loading
1999  #
2000  # Variables:
2001  #   build_config: Path to build_config used for locale lists.
2002  #   is_bundle_module: Whether or not this target is part of a bundle build.
2003  #   java_package: Java package for the generated class.
2004  #   use_chromium_linker:
2005  #   use_modern_linker:
2006  template("generate_product_config_srcjar") {
2007    java_cpp_template(target_name) {
2008      defines = []
2009      _use_final =
2010          defined(invoker.build_config) ||
2011          defined(invoker.use_chromium_linker) ||
2012          defined(invoker.use_modern_linker) || defined(invoker.is_bundle)
2013      if (_use_final) {
2014        defines += [ "USE_FINAL" ]
2015      }
2016
2017      sources = [ "//build/android/java/templates/ProductConfig.template" ]
2018      defines += [ "PACKAGE=${invoker.java_package}" ]
2019
2020      _use_chromium_linker =
2021          defined(invoker.use_chromium_linker) && invoker.use_chromium_linker
2022      _use_modern_linker =
2023          defined(invoker.use_modern_linker) && invoker.use_modern_linker
2024      _is_bundle = defined(invoker.is_bundle_module) && invoker.is_bundle_module
2025      defines += [
2026        "USE_CHROMIUM_LINKER_VALUE=$_use_chromium_linker",
2027        "USE_MODERN_LINKER_VALUE=$_use_modern_linker",
2028        "IS_BUNDLE_VALUE=$_is_bundle",
2029      ]
2030      if (defined(invoker.build_config)) {
2031        forward_variables_from(invoker,
2032                               [
2033                                 "deps",
2034                                 "testonly",
2035                               ])
2036        _rebased_build_config =
2037            rebase_path(invoker.build_config, root_build_dir)
2038        defines += [
2039          "COMPRESSED_LOCALE_LIST=" + "@FileArg($_rebased_build_config:deps_info:compressed_locales_java_list)",
2040          "UNCOMPRESSED_LOCALE_LIST=" + "@FileArg($_rebased_build_config:deps_info:uncompressed_locales_java_list)",
2041        ]
2042      }
2043    }
2044  }
2045
2046  # Declare an Android app module target, which is used as the basis for an
2047  # Android APK or an Android app bundle module.
2048  #
2049  # Supports all variables of android_library(), plus:
2050  #   android_manifest: Path to AndroidManifest.xml. NOTE: This manifest must
2051  #     not contain a <uses-sdk> element. Use [min|target|max]_sdk_version
2052  #     instead.
2053  #   android_manifest_dep: Target that generates AndroidManifest (if applicable)
2054  #   png_to_webp: If true, pngs (with the exception of 9-patch) are
2055  #     converted to webp during resource packaging.
2056  #   loadable_modules: List of paths to native libraries to include. Different
2057  #     from |shared_libraries| in that:
2058  #       * dependencies of this .so are not automatically included
2059  #       * ".cr.so" is never added
2060  #       * they are not side-loaded when incremental_install=true.
2061  #       * load_library_from_apk, use_chromium_linker,
2062  #         and enable_relocation_packing do not apply
2063  #     Use this instead of shared_libraries when you are going to load the library
2064  #     conditionally, and only when shared_libraries doesn't work for you.
2065  #   secondary_abi_loadable_modules: This is the loadable_modules analog to
2066  #     secondary_abi_shared_libraries.
2067  #   shared_libraries: List shared_library targets to bundle. If these
2068  #     libraries depend on other shared_library targets, those dependencies will
2069  #     also be included in the apk (e.g. for is_component_build).
2070  #   secondary_abi_shared_libraries: secondary abi shared_library targets to
2071  #     bundle. If these libraries depend on other shared_library targets, those
2072  #     dependencies will also be included in the apk (e.g. for is_component_build).
2073  #   native_lib_placeholders: List of placeholder filenames to add to the apk
2074  #     (optional).
2075  #   secondary_native_lib_placeholders: List of placeholder filenames to add to
2076  #     the apk for the secondary ABI (optional).
2077  #   generate_buildconfig_java: If defined and false, skip generating the
2078  #     BuildConfig java class describing the build configuration. The default
2079  #     is true for non-test APKs.
2080  #   generate_final_jni: If defined and false, skip generating the
2081  #     GEN_JNI srcjar.
2082  #   jni_registration_header: If specified, causes the
2083  #     ${target_name}__final_jni target to additionally output a
2084  #     header file to this path for use with manual JNI registration.
2085  #   jni_sources_exclusions: List of source path to exclude from the
2086  #     final_jni step.
2087  #   aapt_locale_allowlist: If set, all locales not in this list will be
2088  #     stripped from resources.arsc.
2089  #   resource_exclusion_regex: Causes all drawable images matching the regex to
2090  #     be excluded (mipmaps are still included).
2091  #   resource_exclusion_exceptions: A list of globs used when
2092  #     resource_exclusion_regex is set. Files that match this list will
2093  #     still be included.
2094  #   resource_values_filter_rules: List of "source_path:name_regex" used to
2095  #     filter out unwanted values/ resources.
2096  #   shared_resources: True if this is a runtime shared library APK, like
2097  #     the system_webview_apk target. Ensures that its resources can be
2098  #     used by the loading application process.
2099  #   app_as_shared_lib: True if this is a regular application apk that can
2100  #     also serve as a runtime shared library, like the monochrome_public_apk
2101  #     target. Ensures that the resources are usable both by the APK running
2102  #     as an application, or by another process that loads it at runtime.
2103  #   shared_resources_allowlist_target: Optional name of a target specifying
2104  #     an input R.txt file that lists the resources that can be exported
2105  #     by the APK when shared_resources or app_as_shared_lib is defined.
2106  #   uncompress_shared_libraries: True if shared libraries should be stored
2107  #     uncompressed in the APK. Must be unset or true if load_library_from_apk
2108  #     is set to true.
2109  #   uncompress_dex: Store final .dex files uncompressed in the apk.
2110  #   strip_resource_names: True if resource names should be stripped from the
2111  #     resources.arsc file in the apk or module.
2112  #   short_resource_paths: True if resource paths should be shortened in the
2113  #     apk or module.
2114  #   resources_config_paths: List of paths to the aapt2 optimize config files
2115  #     that tags resources with acceptable/non-acceptable optimizations.
2116  #   expected_android_manifest: Enables verification of expected merged
2117  #     manifest based on a golden file.
2118  #   resource_ids_provider_dep: If passed, this target will use the resource
2119  #     IDs generated by {resource_ids_provider_dep}__compile_res during
2120  #     resource compilation.
2121  #   enforce_resource_overlays_in_tests: Enables check for testonly targets that
2122  #     dependent resource targets which override another target set
2123  #     overlay_resources=true. This check is on for non-test targets and
2124  #     cannot be disabled.
2125  #   static_library_dependent_targets: A list of scopes describing targets that
2126  #     use this target as a static library. Common Java code from the targets
2127  #     listed in static_library_dependent_targets will be moved into this
2128  #     target. Scope members are name and is_resource_ids_provider.
2129  #   static_library_provider: Specifies a single target that this target will
2130  #     use as a static library APK.
2131  #   static_library_synchronized_proguard: When proguard is enabled, the
2132  #     static_library_provider target will provide the dex file(s) for this
2133  #     target.
2134  #   min_sdk_version: The minimum Android SDK version this target supports.
2135  #     Optional, default $default_min_sdk_version.
2136  #   target_sdk_version: The target Android SDK version for this target.
2137  #     Optional, default to android_sdk_version.
2138  #   max_sdk_version: The maximum Android SDK version this target supports.
2139  #     Optional, default not set.
2140  #   require_native_mocks: Enforce that any native calls using
2141  #     org.chromium.base.annotations.NativeMethods must have a mock set
2142  #     (optional).
2143  #   enable_native_mocks: Allow native calls using
2144  #     org.chromium.base.annotations.NativeMethods to be mocked in tests
2145  #     (optional).
2146  #   product_config_java_packages: Optional list of java packages. If given, a
2147  #     ProductConfig.java file will be generated for each package.
2148  #   enable_proguard_checks: Turns on -checkdiscard directives and missing
2149  #     symbols check in the proguard step (default=true).
2150  #   disable_r8_outlining: Turn off outlining during the proguard step.
2151  #   annotation_processor_deps: List of java_annotation_processor targets to
2152  #     use when compiling the sources given to this target (optional).
2153  #   processor_args_javac: List of args to pass to annotation processors when
2154  #     compiling sources given to this target (optional).
2155  #   bundles_supported: Enable Java code to treat this target as a bundle
2156  #     whether (by default determined by the target type).
2157  #   main_component_library: Specifies the name of the base component's library
2158  #     in a component build. If given, the system will find dependent native
2159  #     libraries at runtime by inspecting this library (optional).
2160  #   expected_libs_and_assets: Verify the list of included native libraries
2161  #     and assets is consistent with the given expectation file.
2162  #   expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff
2163  #     with this file as the base.
2164  #   expected_proguard_config: Checks that the merged set of proguard flags
2165  #     matches the given config.
2166  #   expected_proguard_config_base: Treat expected_proguard_config as a diff
2167  #     with this file as the base.
2168  template("android_apk_or_module") {
2169    forward_variables_from(invoker, [ "testonly" ])
2170    assert(defined(invoker.android_manifest))
2171    _base_path = "$target_out_dir/$target_name/$target_name"
2172    _build_config = "$target_gen_dir/$target_name.build_config"
2173    _build_config_target = "$target_name$build_config_target_suffix"
2174
2175    _min_sdk_version = default_min_sdk_version
2176    _target_sdk_version = android_sdk_version
2177    if (defined(invoker.min_sdk_version)) {
2178      _min_sdk_version = invoker.min_sdk_version
2179    }
2180    if (defined(invoker.target_sdk_version)) {
2181      _target_sdk_version = invoker.target_sdk_version
2182    }
2183
2184    _template_name = target_name
2185
2186    _is_bundle_module =
2187        defined(invoker.is_bundle_module) && invoker.is_bundle_module
2188    if (_is_bundle_module) {
2189      _is_base_module =
2190          defined(invoker.is_base_module) && invoker.is_base_module
2191    }
2192
2193    _enable_multidex =
2194        !defined(invoker.enable_multidex) || invoker.enable_multidex
2195
2196    if (!_is_bundle_module) {
2197      _final_apk_path = invoker.final_apk_path
2198      _final_rtxt_path = "${_final_apk_path}.R.txt"
2199    }
2200
2201    _short_resource_paths =
2202        defined(invoker.short_resource_paths) && invoker.short_resource_paths &&
2203        enable_arsc_obfuscation
2204    _strip_resource_names =
2205        defined(invoker.strip_resource_names) && invoker.strip_resource_names &&
2206        enable_arsc_obfuscation
2207    _optimize_resources = _strip_resource_names || _short_resource_paths
2208
2209    if (!_is_bundle_module && _short_resource_paths) {
2210      _final_pathmap_path = "${_final_apk_path}.pathmap.txt"
2211    }
2212    _res_size_info_path = "$target_out_dir/$target_name.ap_.info"
2213    if (!_is_bundle_module) {
2214      _final_apk_path_no_ext_list =
2215          process_file_template([ _final_apk_path ],
2216                                "{{source_dir}}/{{source_name_part}}")
2217      _final_apk_path_no_ext = _final_apk_path_no_ext_list[0]
2218      not_needed([ "_final_apk_path_no_ext" ])
2219    }
2220
2221    # Non-base bundle modules create only proto resources.
2222    if (!_is_bundle_module || _is_base_module) {
2223      _arsc_resources_path = "$target_out_dir/$target_name.ap_"
2224    }
2225    if (_is_bundle_module) {
2226      # Path to the intermediate proto-format resources zip file.
2227      _proto_resources_path = "$target_out_dir/$target_name.proto.ap_"
2228      if (_optimize_resources) {
2229        _optimized_proto_resources_path =
2230            "$target_out_dir/$target_name.optimized.proto.ap_"
2231      }
2232    } else {
2233      # resource_sizes.py needs to be able to find the unpacked resources.arsc
2234      # file based on apk name to compute normatlized size.
2235      _resource_sizes_arsc_path =
2236          "$root_out_dir/arsc/" +
2237          rebase_path(_final_apk_path_no_ext, root_build_dir) + ".ap_"
2238      if (_optimize_resources) {
2239        _optimized_arsc_resources_path =
2240            "$target_out_dir/$target_name.optimized.ap_"
2241      }
2242    }
2243
2244    if (defined(invoker.version_code)) {
2245      _version_code = invoker.version_code
2246    } else {
2247      _version_code = android_default_version_code
2248    }
2249
2250    if (android_override_version_code != "") {
2251      _version_code = android_override_version_code
2252    }
2253
2254    if (defined(invoker.version_name)) {
2255      _version_name = invoker.version_name
2256    } else {
2257      _version_name = android_default_version_name
2258    }
2259
2260    if (android_override_version_name != "") {
2261      _version_name = android_override_version_name
2262    }
2263
2264    _deps = []
2265    if (defined(invoker.deps)) {
2266      _deps = invoker.deps
2267    }
2268
2269    _srcjar_deps = []
2270    if (defined(invoker.srcjar_deps)) {
2271      _srcjar_deps = invoker.srcjar_deps
2272    }
2273
2274    _android_root_manifest_deps = []
2275    if (defined(invoker.android_manifest_dep)) {
2276      _android_root_manifest_deps = [ invoker.android_manifest_dep ]
2277    }
2278    _android_root_manifest = invoker.android_manifest
2279
2280    _use_chromium_linker =
2281        defined(invoker.use_chromium_linker) && invoker.use_chromium_linker
2282    _use_modern_linker =
2283        defined(invoker.use_modern_linker) && invoker.use_modern_linker
2284
2285    _load_library_from_apk =
2286        defined(invoker.load_library_from_apk) && invoker.load_library_from_apk
2287
2288    not_needed([
2289                 "_use_chromium_linker",
2290                 "_use_modern_linker",
2291               ])
2292    assert(!_load_library_from_apk || _use_chromium_linker,
2293           "load_library_from_apk requires use_chromium_linker")
2294
2295    # Make sure that uncompress_shared_libraries is set to true if
2296    # load_library_from_apk is true.
2297    if (defined(invoker.uncompress_shared_libraries)) {
2298      _uncompress_shared_libraries = invoker.uncompress_shared_libraries
2299      assert(!_load_library_from_apk || _uncompress_shared_libraries)
2300    } else {
2301      _uncompress_shared_libraries = _load_library_from_apk
2302    }
2303
2304    # The dependency that makes the chromium linker, if any is needed.
2305    _native_libs_deps = []
2306    _shared_libraries_is_valid =
2307        defined(invoker.shared_libraries) && invoker.shared_libraries != []
2308
2309    if (_shared_libraries_is_valid) {
2310      _native_libs_deps += invoker.shared_libraries
2311
2312      # Write shared library output files of all dependencies to a file. Those
2313      # will be the shared libraries packaged into the APK.
2314      _shared_library_list_file =
2315          "$target_gen_dir/${_template_name}.native_libs"
2316      generated_file("${_template_name}__shared_library_list") {
2317        deps = _native_libs_deps
2318        outputs = [ _shared_library_list_file ]
2319        data_keys = [ "shared_libraries" ]
2320        walk_keys = [ "shared_libraries_barrier" ]
2321        rebase = root_build_dir
2322      }
2323    } else {
2324      # Must exist for instrumentation_test_apk() to depend on.
2325      group("${_template_name}__shared_library_list") {
2326      }
2327    }
2328
2329    _secondary_abi_native_libs_deps = []
2330
2331    if (defined(invoker.secondary_abi_shared_libraries) &&
2332        invoker.secondary_abi_shared_libraries != []) {
2333      _secondary_abi_native_libs_deps = invoker.secondary_abi_shared_libraries
2334
2335      # Write shared library output files of all dependencies to a file. Those
2336      # will be the shared libraries packaged into the APK.
2337      _secondary_abi_shared_library_list_file =
2338          "$target_gen_dir/${_template_name}.secondary_abi_native_libs"
2339      generated_file("${_template_name}__secondary_abi_shared_library_list") {
2340        deps = _secondary_abi_native_libs_deps
2341        outputs = [ _secondary_abi_shared_library_list_file ]
2342        data_keys = [ "shared_libraries" ]
2343        walk_keys = [ "shared_libraries_barrier" ]
2344        rebase = root_build_dir
2345      }
2346    } else {
2347      # Must exist for instrumentation_test_apk() to depend on.
2348      group("${_template_name}__secondary_abi_shared_library_list") {
2349      }
2350    }
2351
2352    _rebased_build_config = rebase_path(_build_config, root_build_dir)
2353    assert(_rebased_build_config != "")  # Mark as used.
2354
2355    _generate_buildconfig_java = !defined(invoker.apk_under_test)
2356    if (defined(invoker.generate_buildconfig_java)) {
2357      _generate_buildconfig_java = invoker.generate_buildconfig_java
2358    }
2359
2360    _generate_productconfig_java = defined(invoker.product_config_java_packages)
2361
2362    # JNI generation usually goes hand-in-hand with buildconfig generation.
2363    _generate_final_jni = _generate_buildconfig_java
2364    if (defined(invoker.generate_final_jni)) {
2365      _generate_final_jni = invoker.generate_final_jni
2366    }
2367
2368    _proguard_enabled =
2369        defined(invoker.proguard_enabled) && invoker.proguard_enabled
2370
2371    if (!_is_bundle_module && _proguard_enabled) {
2372      _proguard_mapping_path = "$_final_apk_path.mapping"
2373    }
2374
2375    # TODO(http://crbug.com/901465): Move shared Java code to static libraries
2376    # when !_proguard_enabled too.
2377    _is_static_library_provider =
2378        defined(invoker.static_library_dependent_targets) && _proguard_enabled
2379    if (_is_static_library_provider) {
2380      _static_library_sync_dex_path = "$_base_path.synchronized.r8dex.jar"
2381      _resource_ids_provider_deps = []
2382      foreach(_target, invoker.static_library_dependent_targets) {
2383        if (_target.is_resource_ids_provider) {
2384          assert(_resource_ids_provider_deps == [],
2385                 "Can only have 1 resource_ids_provider_dep")
2386          _resource_ids_provider_deps += [ _target.name ]
2387        }
2388      }
2389      _resource_ids_provider_dep = _resource_ids_provider_deps[0]
2390    } else if (defined(invoker.resource_ids_provider_dep)) {
2391      _resource_ids_provider_dep = invoker.resource_ids_provider_dep
2392    }
2393
2394    if (_is_static_library_provider) {
2395      _shared_resources_allowlist_target = _resource_ids_provider_dep
2396    } else if (defined(invoker.shared_resources_allowlist_target)) {
2397      _shared_resources_allowlist_target =
2398          invoker.shared_resources_allowlist_target
2399    }
2400
2401    _uses_static_library = defined(invoker.static_library_provider)
2402    _uses_static_library_synchronized_proguard =
2403        defined(invoker.static_library_synchronized_proguard) &&
2404        invoker.static_library_synchronized_proguard
2405
2406    if (_uses_static_library_synchronized_proguard) {
2407      assert(_uses_static_library)
2408
2409      # These will be provided by the static library APK.
2410      _generate_buildconfig_java = false
2411      _generate_final_jni = false
2412    }
2413
2414    # TODO(crbug.com/864142): Allow incremental installs of bundle modules.
2415    _incremental_apk = !_is_bundle_module &&
2416                       !(defined(invoker.never_incremental) &&
2417                         invoker.never_incremental) && incremental_install
2418    if (_incremental_apk) {
2419      _target_dir_name = get_label_info(target_name, "dir")
2420      _incremental_install_json_path = "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.incremental.json"
2421      _incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk"
2422    }
2423
2424    if (!_incremental_apk) {
2425      # Bundle modules don't build the dex here, but need to write this path
2426      # to their .build_config file.
2427      if (_proguard_enabled) {
2428        _final_dex_path = "$_base_path.r8dex.jar"
2429      } else {
2430        _final_dex_path = "$_base_path.mergeddex.jar"
2431      }
2432    }
2433
2434    _android_manifest =
2435        "$target_gen_dir/${_template_name}_manifest/AndroidManifest.xml"
2436    _merge_manifest_target = "${_template_name}__merge_manifests"
2437    merge_manifests(_merge_manifest_target) {
2438      forward_variables_from(invoker,
2439                             [
2440                               "manifest_package",
2441                               "max_sdk_version",
2442                             ])
2443      input_manifest = _android_root_manifest
2444      output_manifest = _android_manifest
2445      build_config = _build_config
2446      min_sdk_version = _min_sdk_version
2447      target_sdk_version = _target_sdk_version
2448      deps = _android_root_manifest_deps + [ ":$_build_config_target" ]
2449    }
2450
2451    _final_deps = []
2452
2453    _enable_main_dex_list = _enable_multidex && _min_sdk_version < 21
2454    if (_enable_main_dex_list) {
2455      _generated_proguard_main_dex_config =
2456          "$_base_path.resources.main-dex-proguard.txt"
2457    }
2458    _generated_proguard_config = "$_base_path.resources.proguard.txt"
2459
2460    if (_generate_buildconfig_java &&
2461        defined(invoker.product_version_resources_dep)) {
2462      # Needs to be added as a .build_config dep to pick up resources.
2463      _deps += [ invoker.product_version_resources_dep ]
2464    }
2465
2466    if (defined(invoker.alternative_android_sdk_dep)) {
2467      _android_sdk_dep = invoker.alternative_android_sdk_dep
2468    } else {
2469      _android_sdk_dep = "//third_party/android_sdk:android_sdk_java"
2470    }
2471
2472    if (defined(_shared_resources_allowlist_target)) {
2473      _allowlist_gen_dir =
2474          get_label_info(_shared_resources_allowlist_target, "target_gen_dir")
2475      _allowlist_target_name =
2476          get_label_info(_shared_resources_allowlist_target, "name")
2477      _allowlist_r_txt_path =
2478          "${_allowlist_gen_dir}/${_allowlist_target_name}" +
2479          "__compile_resources_R.txt"
2480      _allowlist_deps =
2481          "${_shared_resources_allowlist_target}__compile_resources"
2482    }
2483
2484    if (_short_resource_paths) {
2485      _resources_path_map_out_path =
2486          "${target_gen_dir}/${_template_name}_resources_path_map.txt"
2487    }
2488
2489    _compile_resources_target = "${_template_name}__compile_resources"
2490    _compile_resources_rtxt_out =
2491        "${target_gen_dir}/${_compile_resources_target}_R.txt"
2492    _compile_resources_emit_ids_out =
2493        "${target_gen_dir}/${_compile_resources_target}.resource_ids"
2494    compile_resources(_compile_resources_target) {
2495      forward_variables_from(invoker,
2496                             [
2497                               "aapt_locale_allowlist",
2498                               "app_as_shared_lib",
2499                               "enforce_resource_overlays_in_tests",
2500                               "expected_android_manifest",
2501                               "expected_android_manifest_base",
2502                               "manifest_package",
2503                               "max_sdk_version",
2504                               "no_xml_namespaces",
2505                               "package_id",
2506                               "package_name",
2507                               "png_to_webp",
2508                               "r_java_root_package_name",
2509                               "resource_exclusion_exceptions",
2510                               "resource_exclusion_regex",
2511                               "resource_values_filter_rules",
2512                               "resources_config_paths",
2513                               "shared_resources",
2514                               "shared_resources_allowlist_locales",
2515                               "support_zh_hk",
2516                               "uses_split",
2517                             ])
2518      short_resource_paths = _short_resource_paths
2519      strip_resource_names = _strip_resource_names
2520      android_manifest = _android_manifest
2521      android_manifest_dep = ":$_merge_manifest_target"
2522      version_code = _version_code
2523      version_name = _version_name
2524      min_sdk_version = _min_sdk_version
2525      target_sdk_version = _target_sdk_version
2526
2527      if (defined(expected_android_manifest)) {
2528        top_target_name = _template_name
2529      }
2530
2531      if (defined(_resource_ids_provider_dep)) {
2532        resource_ids_provider_dep = _resource_ids_provider_dep
2533      }
2534
2535      if (defined(invoker.post_process_package_resources_script)) {
2536        post_process_script = invoker.post_process_package_resources_script
2537      }
2538      r_text_out_path = _compile_resources_rtxt_out
2539      emit_ids_out_path = _compile_resources_emit_ids_out
2540      size_info_path = _res_size_info_path
2541      proguard_file = _generated_proguard_config
2542      if (_enable_main_dex_list) {
2543        proguard_file_main_dex = _generated_proguard_main_dex_config
2544      }
2545      if (_short_resource_paths) {
2546        resources_path_map_out_path = _resources_path_map_out_path
2547      }
2548
2549      build_config = _build_config
2550      build_config_dep = ":$_build_config_target"
2551      android_sdk_dep = _android_sdk_dep
2552      deps = _deps
2553
2554      # The static library uses the R.txt files generated by the
2555      # static_library_dependent_targets when generating the final R.java file.
2556      if (_is_static_library_provider) {
2557        foreach(_dep, invoker.static_library_dependent_targets) {
2558          deps += [ "${_dep.name}__compile_resources" ]
2559        }
2560      }
2561
2562      if (defined(invoker.apk_under_test)) {
2563        # Set the arsc package name to match the apk_under_test package name
2564        # So that test resources can references under_test resources via
2565        # @type/name syntax.
2566        r_java_root_package_name = "test"
2567        arsc_package_name =
2568            "@FileArg($_rebased_build_config:deps_info:arsc_package_name)"
2569
2570        # Passing in the --emit-ids mapping will cause aapt2 to assign resources
2571        # IDs that do not conflict with those from apk_under_test.
2572        assert(!defined(resource_ids_provider_dep))
2573        resource_ids_provider_dep = invoker.apk_under_test
2574
2575        include_resource =
2576            get_label_info(invoker.apk_under_test, "target_out_dir") + "/" +
2577            get_label_info(invoker.apk_under_test, "name") + ".ap_"
2578        _link_against = invoker.apk_under_test
2579      }
2580
2581      if (_is_bundle_module) {
2582        is_bundle_module = true
2583        proto_output = _proto_resources_path
2584        if (_optimize_resources) {
2585          optimized_proto_output = _optimized_proto_resources_path
2586        }
2587
2588        if (defined(invoker.base_module_target)) {
2589          include_resource =
2590              get_label_info(invoker.base_module_target, "target_out_dir") +
2591              "/" + get_label_info(invoker.base_module_target, "name") + ".ap_"
2592          _link_against = invoker.base_module_target
2593        }
2594      } else if (_optimize_resources) {
2595        optimized_arsc_output = _optimized_arsc_resources_path
2596      }
2597
2598      if (defined(_link_against)) {
2599        deps += [ "${_link_against}__compile_resources" ]
2600        include_resource = get_label_info(_link_against, "target_out_dir") +
2601                           "/" + get_label_info(_link_against, "name") + ".ap_"
2602      }
2603
2604      # Bundle modules have to reference resources from the base module.
2605      if (!_is_bundle_module || _is_base_module) {
2606        arsc_output = _arsc_resources_path
2607      }
2608
2609      if (defined(_shared_resources_allowlist_target)) {
2610        # Used to ensure that the WebView resources are properly shared
2611        # (i.e. are non-final and with package ID 0).
2612        shared_resources_allowlist = _allowlist_r_txt_path
2613        deps += [ _allowlist_deps ]
2614      }
2615    }
2616    _srcjar_deps += [ ":$_compile_resources_target" ]
2617
2618    if (defined(_resource_sizes_arsc_path)) {
2619      _copy_arsc_target = "${_template_name}__copy_arsc"
2620      copy(_copy_arsc_target) {
2621        deps = [ ":$_compile_resources_target" ]
2622
2623        # resource_sizes.py doesn't care if it gets the optimized .arsc.
2624        sources = [ _arsc_resources_path ]
2625        outputs = [ _resource_sizes_arsc_path ]
2626      }
2627      _final_deps += [ ":$_copy_arsc_target" ]
2628    }
2629
2630    if (!_is_bundle_module) {
2631      # Output the R.txt file to a more easily discoverable location for
2632      # archiving. This is necessary when stripping resource names so that we
2633      # have an archive of resource names to ids for shipped apks (for
2634      # debugging purposes). We copy the file rather than change the location
2635      # of the original because other targets rely on the location of the R.txt
2636      # file.
2637      _copy_rtxt_target = "${_template_name}__copy_rtxt"
2638      copy(_copy_rtxt_target) {
2639        deps = [ ":$_compile_resources_target" ]
2640        sources = [ _compile_resources_rtxt_out ]
2641        outputs = [ _final_rtxt_path ]
2642      }
2643      _final_deps += [ ":$_copy_rtxt_target" ]
2644
2645      if (_short_resource_paths) {
2646        # Do the same for path map
2647        _copy_pathmap_target = "${_template_name}__copy_pathmap"
2648        copy(_copy_pathmap_target) {
2649          deps = [ ":$_compile_resources_target" ]
2650          sources = [ _resources_path_map_out_path ]
2651          outputs = [ _final_pathmap_path ]
2652
2653          # The monochrome_public_apk_checker test needs pathmap when run on swarming.
2654          data = [ _final_pathmap_path ]
2655        }
2656        _final_deps += [ ":$_copy_pathmap_target" ]
2657      }
2658    }
2659
2660    _generate_native_libraries_java =
2661        (!_is_bundle_module || _is_base_module) &&
2662        (_native_libs_deps != [] || _secondary_abi_native_libs_deps != []) &&
2663        !_uses_static_library_synchronized_proguard
2664    if (_generate_native_libraries_java) {
2665      write_native_libraries_java("${_template_name}__native_libraries") {
2666        forward_variables_from(invoker, [ "main_component_library" ])
2667        deps = []
2668        if (defined(invoker.native_lib_version_rule)) {
2669          deps += [ invoker.native_lib_version_rule ]
2670        }
2671        if (defined(invoker.native_lib_version_arg)) {
2672          version_number = invoker.native_lib_version_arg
2673        }
2674
2675        # Do not add a dep on the generated_file target in order to avoid having
2676        # to build the native libraries before this target. The dependency is
2677        # instead captured via a depfile.
2678        if (_native_libs_deps != []) {
2679          native_libraries_list_file = _shared_library_list_file
2680        } else {
2681          native_libraries_list_file = _secondary_abi_shared_library_list_file
2682        }
2683        enable_chromium_linker = _use_chromium_linker
2684        load_library_from_apk = _load_library_from_apk
2685        use_modern_linker = _use_modern_linker
2686        use_final_fields = true
2687      }
2688      _srcjar_deps += [ ":${_template_name}__native_libraries" ]
2689    } else {
2690      if (defined(invoker.native_lib_version_arg)) {
2691        not_needed(invoker, [ "native_lib_version_arg" ])
2692      }
2693      if (defined(invoker.native_lib_version_rule)) {
2694        not_needed(invoker, [ "native_lib_version_rule" ])
2695      }
2696    }
2697
2698    _loadable_modules = []
2699    if (defined(invoker.loadable_modules)) {
2700      _loadable_modules = invoker.loadable_modules
2701    }
2702
2703    if (_native_libs_deps != []) {
2704      _loadable_modules += _sanitizer_runtimes
2705    }
2706
2707    if (_generate_buildconfig_java) {
2708      generate_build_config_srcjar("${_template_name}__build_config_srcjar") {
2709        forward_variables_from(invoker,
2710                               [
2711                                 "min_sdk_version",
2712                                 "isolated_splits_enabled",
2713                               ])
2714        _bundles_supported = _is_bundle_module || _is_static_library_provider
2715        if (defined(invoker.bundles_supported)) {
2716          _bundles_supported = invoker.bundles_supported
2717        }
2718        bundles_supported = _bundles_supported
2719        use_final_fields = true
2720        enable_multidex = _enable_multidex
2721        is_incremental_install = _incremental_apk
2722        if (defined(invoker.product_version_resources_dep)) {
2723          resources_version_variable =
2724              "org.chromium.base.R.string.product_version"
2725        }
2726        deps = [ ":$_build_config_target" ]
2727      }
2728      _srcjar_deps += [ ":${_template_name}__build_config_srcjar" ]
2729    }
2730
2731    if (_generate_productconfig_java) {
2732      foreach(_package, invoker.product_config_java_packages) {
2733        _locale_target_name =
2734            "${_template_name}_${_package}__product_config_srcjar"
2735        generate_product_config_srcjar("$_locale_target_name") {
2736          forward_variables_from(invoker, [ "is_bundle_module" ])
2737          build_config = _build_config
2738          java_package = _package
2739          use_chromium_linker = _use_chromium_linker
2740          use_modern_linker = _use_modern_linker
2741          deps = [ ":$_build_config_target" ]
2742        }
2743        _srcjar_deps += [ ":$_locale_target_name" ]
2744      }
2745    }
2746
2747    if (_generate_final_jni) {
2748      generate_jni_registration("${_template_name}__final_jni") {
2749        forward_variables_from(invoker,
2750                               [
2751                                 "enable_native_mocks",
2752                                 "require_native_mocks",
2753                               ])
2754        if (defined(invoker.bundle_target)) {
2755          targets = [ invoker.bundle_target ]
2756        } else {
2757          targets = [ ":$_template_name" ]
2758        }
2759        if (_is_static_library_provider) {
2760          foreach(_target, invoker.static_library_dependent_targets) {
2761            targets += [ _target.name ]
2762          }
2763        }
2764        if (defined(invoker.jni_registration_header)) {
2765          header_output = invoker.jni_registration_header
2766        }
2767        if (defined(invoker.jni_sources_exclusions)) {
2768          sources_exclusions = invoker.jni_sources_exclusions
2769        }
2770      }
2771      _srcjar_deps += [ ":${_template_name}__final_jni" ]
2772    }
2773
2774    _java_target = "${_template_name}__java"
2775
2776    java_library_impl(_java_target) {
2777      forward_variables_from(invoker,
2778                             [
2779                               "alternative_android_sdk_dep",
2780                               "android_manifest",
2781                               "android_manifest_dep",
2782                               "annotation_processor_deps",
2783                               "apk_under_test",
2784                               "base_module_target",
2785                               "chromium_code",
2786                               "enable_jetify",
2787                               "jacoco_never_instrument",
2788                               "jar_excluded_patterns",
2789                               "javac_args",
2790                               "native_lib_placeholders",
2791                               "processor_args_javac",
2792                               "secondary_abi_loadable_modules",
2793                               "secondary_native_lib_placeholders",
2794                               "sources",
2795                               "static_library_dependent_targets",
2796                               "library_always_compress",
2797                               "library_renames",
2798                             ])
2799      deps = _deps
2800      if (_uses_static_library_synchronized_proguard) {
2801        if (!defined(jar_excluded_patterns)) {
2802          jar_excluded_patterns = []
2803        }
2804
2805        # The static library will provide all R.java files, but we still need to
2806        # make the base module R.java files available at compile time since DFM
2807        # R.java classes extend base module classes.
2808        jar_excluded_patterns += [
2809          "*/R.class",
2810          "*/R\$*.class",
2811        ]
2812      }
2813      if (_is_bundle_module) {
2814        type = "android_app_bundle_module"
2815        res_size_info_path = _res_size_info_path
2816        is_base_module = _is_base_module
2817        forward_variables_from(invoker,
2818                               [
2819                                 "version_code",
2820                                 "version_name",
2821                               ])
2822      } else {
2823        type = "android_apk"
2824      }
2825      r_text_path = _compile_resources_rtxt_out
2826      main_target_name = _template_name
2827      supports_android = true
2828      requires_android = true
2829      srcjar_deps = _srcjar_deps
2830      if (defined(_final_dex_path)) {
2831        final_dex_path = _final_dex_path
2832      }
2833
2834      if (_is_bundle_module) {
2835        proto_resources_path = _proto_resources_path
2836        if (_optimize_resources) {
2837          proto_resources_path = _optimized_proto_resources_path
2838          if (_short_resource_paths) {
2839            module_pathmap_path = _resources_path_map_out_path
2840          }
2841        }
2842      } else {
2843        apk_path = _final_apk_path
2844        if (_incremental_apk) {
2845          incremental_apk_path = _incremental_apk_path
2846          incremental_install_json_path = _incremental_install_json_path
2847        }
2848      }
2849
2850      proguard_enabled = _proguard_enabled
2851      if (_proguard_enabled) {
2852        proguard_configs = [ _generated_proguard_config ]
2853        if (defined(invoker.proguard_configs)) {
2854          proguard_configs += invoker.proguard_configs
2855        }
2856        if (_enable_main_dex_list) {
2857          proguard_configs += [ "//build/android/multidex.flags" ]
2858        }
2859        if (!dcheck_always_on && (!defined(testonly) || !testonly) &&
2860            # Injected JaCoCo code causes -checkdiscards to fail.
2861            !use_jacoco_coverage) {
2862          proguard_configs += [ "//build/android/dcheck_is_off.flags" ]
2863        }
2864        if (!_is_bundle_module) {
2865          proguard_mapping_path = _proguard_mapping_path
2866        }
2867      }
2868
2869      # Do not add a dep on the generated_file target in order to avoid having
2870      # to build the native libraries before this target. The dependency is
2871      # instead captured via a depfile.
2872      if (_native_libs_deps != []) {
2873        shared_libraries_runtime_deps_file = _shared_library_list_file
2874      }
2875      if (defined(_secondary_abi_shared_library_list_file)) {
2876        secondary_abi_shared_libraries_runtime_deps_file =
2877            _secondary_abi_shared_library_list_file
2878      }
2879
2880      loadable_modules = _loadable_modules
2881
2882      uncompress_shared_libraries = _uncompress_shared_libraries
2883
2884      if (defined(_allowlist_r_txt_path) && _is_bundle_module) {
2885        # Used to write the file path to the target's .build_config only.
2886        base_allowlist_rtxt_path = _allowlist_r_txt_path
2887      }
2888    }
2889
2890    # TODO(cjhopman): This is only ever needed to calculate the list of tests to
2891    # run. See build/android/pylib/instrumentation/test_jar.py. We should be
2892    # able to just do that calculation at build time instead.
2893    if (defined(invoker.dist_ijar_path)) {
2894      _dist_ijar_path = invoker.dist_ijar_path
2895      dist_jar("${_template_name}_dist_ijar") {
2896        override_build_config = _build_config
2897        output = _dist_ijar_path
2898        data = [ _dist_ijar_path ]
2899        use_interface_jars = true
2900        deps = [
2901          ":$_build_config_target",
2902          ":$_java_target",
2903        ]
2904      }
2905    }
2906
2907    if (_uses_static_library_synchronized_proguard) {
2908      _final_dex_target_dep = "${invoker.static_library_provider}__dexsplitter"
2909    } else if (_is_bundle_module && _proguard_enabled) {
2910      _final_deps += [ ":$_java_target" ]
2911    } else if (_incremental_apk) {
2912      if (defined(invoker.negative_main_dex_globs)) {
2913        not_needed(invoker, [ "negative_main_dex_globs" ])
2914      }
2915      if (defined(invoker.enable_proguard_checks)) {
2916        not_needed(invoker, [ "enable_proguard_checks" ])
2917      }
2918      if (defined(invoker.disable_r8_outlining)) {
2919        not_needed(invoker, [ "disable_r8_outlining" ])
2920      }
2921      if (defined(invoker.negative_main_dex_globs)) {
2922        not_needed(invoker, [ "negative_main_dex_globs" ])
2923      }
2924      if (defined(invoker.dexlayout_profile)) {
2925        not_needed(invoker, [ "dexlayout_profile" ])
2926      }
2927    } else {
2928      # Dex generation for app bundle modules with proguarding enabled takes
2929      # place later due to synchronized proguarding. For more details,
2930      # read build/android/docs/android_app_bundles.md
2931      _final_dex_target_name = "${_template_name}__final_dex"
2932      dex(_final_dex_target_name) {
2933        forward_variables_from(invoker,
2934                               [
2935                                 "disable_r8_outlining",
2936                                 "dexlayout_profile",
2937                                 "enable_proguard_checks",
2938                               ])
2939        min_sdk_version = _min_sdk_version
2940        proguard_enabled = _proguard_enabled
2941        build_config = _build_config
2942        deps = [
2943          ":$_build_config_target",
2944          ":$_java_target",
2945        ]
2946        if (_proguard_enabled) {
2947          deps += _deps + [ ":$_compile_resources_target" ]
2948          proguard_mapping_path = _proguard_mapping_path
2949          proguard_sourcefile_suffix = "$android_channel-$_version_code"
2950          has_apk_under_test = defined(invoker.apk_under_test)
2951        } else if (_min_sdk_version >= default_min_sdk_version) {
2952          # Enable dex merging only when min_sdk_version is >= what the library
2953          # .dex files were created with.
2954          input_dex_filearg =
2955              "@FileArg(${_rebased_build_config}:final_dex:all_dex_files)"
2956          if (_enable_main_dex_list) {
2957            if (defined(invoker.apk_under_test)) {
2958              main_dex_list_input_classes_filearg = "@FileArg(${_rebased_build_config}:deps_info:device_classpath_extended)"
2959            } else {
2960              main_dex_list_input_classes_filearg = "@FileArg(${_rebased_build_config}:deps_info:device_classpath)"
2961            }
2962          }
2963        } else {
2964          input_classes_filearg =
2965              "@FileArg($_rebased_build_config:deps_info:device_classpath)"
2966        }
2967
2968        if (_is_static_library_provider) {
2969          # The list of input jars is already recorded in the .build_config, but
2970          # we need to explicitly add the java deps here to ensure they're
2971          # available to be used as inputs to the dex step.
2972          foreach(_dep, invoker.static_library_dependent_targets) {
2973            _target_label = get_label_info(_dep.name, "label_no_toolchain")
2974            deps += [ "${_target_label}__java" ]
2975          }
2976          output = _static_library_sync_dex_path
2977          is_static_library = true
2978        } else {
2979          output = _final_dex_path
2980        }
2981        enable_multidex = _enable_multidex
2982
2983        if (_enable_main_dex_list) {
2984          forward_variables_from(invoker, [ "negative_main_dex_globs" ])
2985          extra_main_dex_proguard_config = _generated_proguard_main_dex_config
2986          deps += [ ":$_compile_resources_target" ]
2987        } else if (_enable_multidex &&
2988                   defined(invoker.negative_main_dex_globs)) {
2989          not_needed(invoker, [ "negative_main_dex_globs" ])
2990        }
2991      }
2992
2993      _final_dex_target_dep = ":$_final_dex_target_name"
2994
2995      # For static libraries, a single Proguard run is performed that includes
2996      # code from the static library APK and the APKs that use the static
2997      # library (done via. classpath merging in write_build_config.py).
2998      # This dexsplitter target splits the synchronized dex output into dex
2999      # files for each APK/Bundle. In the Bundle case, another dexsplitter step
3000      # is later performed to split the dex further for each feature module.
3001      if (_is_static_library_provider && _proguard_enabled) {
3002        _static_library_modules = []
3003        foreach(_target, invoker.static_library_dependent_targets) {
3004          _apk_as_module = _target.name
3005          _module_config_target = "${_apk_as_module}$build_config_target_suffix"
3006          _module_gen_dir = get_label_info(_apk_as_module, "target_gen_dir")
3007          _module_name = get_label_info(_apk_as_module, "name")
3008          _module_config = "$_module_gen_dir/$_module_name.build_config"
3009          _static_library_modules += [
3010            {
3011              name = _module_name
3012              build_config = _module_config
3013              build_config_target = _module_config_target
3014            },
3015          ]
3016        }
3017
3018        _static_library_dexsplitter_target = "${_template_name}__dexsplitter"
3019        dexsplitter(_static_library_dexsplitter_target) {
3020          input_dex_zip = _static_library_sync_dex_path
3021          proguard_mapping = _proguard_mapping_path
3022          deps = [
3023            ":$_build_config_target",
3024            "$_final_dex_target_dep",
3025          ]
3026          all_modules = [
3027                          {
3028                            name = "base"
3029                            build_config = _build_config
3030                            build_config_target = ":$_build_config_target"
3031                          },
3032                        ] + _static_library_modules
3033          feature_jars_args = [
3034            "--feature-jars",
3035            "@FileArg($_rebased_build_config:deps_info:" +
3036                "static_library_dependent_classpath_configs:" +
3037                "$_rebased_build_config)",
3038          ]
3039          foreach(_module, _static_library_modules) {
3040            _rebased_module_config =
3041                rebase_path(_module.build_config, root_build_dir)
3042            feature_jars_args += [
3043              "--feature-jars",
3044              "@FileArg($_rebased_build_config:deps_info:" +
3045                  "static_library_dependent_classpath_configs:" +
3046                  "$_rebased_module_config)",
3047            ]
3048          }
3049        }
3050        _final_deps += [ ":$_static_library_dexsplitter_target" ]
3051        _validate_dex_target = "${_template_name}__validate_dex"
3052        action_with_pydeps(_validate_dex_target) {
3053          depfile = "$target_gen_dir/$target_name.d"
3054          script =
3055              "//build/android/gyp/validate_static_library_dex_references.py"
3056          inputs = [ _build_config ]
3057          _stamp = "$target_gen_dir/$target_name.stamp"
3058          outputs = [ _stamp ]
3059          deps = [
3060            ":$_build_config_target",
3061            ":$_static_library_dexsplitter_target",
3062          ]
3063          args = [
3064            "--depfile",
3065            rebase_path(depfile, root_build_dir),
3066            "--stamp",
3067            rebase_path(_stamp, root_build_dir),
3068            "--static-library-dex",
3069            "@FileArg($_rebased_build_config:final_dex:path)",
3070          ]
3071          foreach(_module, _static_library_modules) {
3072            inputs += [ _module.build_config ]
3073            _rebased_config = rebase_path(_module.build_config, root_build_dir)
3074            deps += [ _module.build_config_target ]
3075            args += [
3076              "--static-library-dependent-dex",
3077              "@FileArg($_rebased_config:final_dex:path)",
3078            ]
3079          }
3080        }
3081
3082        # TODO(crbug.com/1032609): Switch to using R8's support for feature
3083        # aware ProGuard and get rid of "_validate_dex_target" or figure out
3084        # why some classes aren't properly being kept.
3085        # _final_deps += [ ":$_validate_dex_target" ]
3086        _final_dex_target_dep = ":$_static_library_dexsplitter_target"
3087      }
3088    }
3089
3090    _all_native_libs_deps = _native_libs_deps + _secondary_abi_native_libs_deps
3091    if (_all_native_libs_deps != []) {
3092      _native_libs_filearg_dep = ":$_build_config_target"
3093      _all_native_libs_deps += [ _native_libs_filearg_dep ]
3094
3095      if (!_is_bundle_module) {
3096        _native_libs_filearg =
3097            "@FileArg($_rebased_build_config:native:libraries)"
3098      }
3099    }
3100
3101    if (_is_bundle_module) {
3102      _final_deps += [
3103                       ":$_merge_manifest_target",
3104                       ":$_build_config_target",
3105                       ":$_compile_resources_target",
3106                     ] + _all_native_libs_deps
3107      if (defined(_final_dex_target_dep)) {
3108        not_needed([ "_final_dex_target_dep" ])
3109      }
3110    } else {
3111      # Generate size-info/*.jar.info files.
3112      if (defined(invoker.name)) {
3113        # Create size info files for targets that care about size
3114        # (have proguard enabled).
3115        if (_proguard_enabled) {
3116          _size_info_target = "${target_name}__size_info"
3117          create_size_info_files(_size_info_target) {
3118            name = "${invoker.name}.apk"
3119            build_config = _build_config
3120            res_size_info_path = _res_size_info_path
3121            deps = _deps + [
3122                     ":$_build_config_target",
3123                     ":$_compile_resources_target",
3124                     ":$_java_target",
3125                   ]
3126          }
3127          _final_deps += [ ":$_size_info_target" ]
3128        } else {
3129          not_needed(invoker, [ "name" ])
3130        }
3131      }
3132
3133      _keystore_path = android_keystore_path
3134      _keystore_name = android_keystore_name
3135      _keystore_password = android_keystore_password
3136
3137      if (defined(invoker.keystore_path)) {
3138        _keystore_path = invoker.keystore_path
3139        _keystore_name = invoker.keystore_name
3140        _keystore_password = invoker.keystore_password
3141      }
3142
3143      if (_incremental_apk) {
3144        _incremental_compiled_resources_path = "${_base_path}_incremental.ap_"
3145        _incremental_compile_resources_target_name =
3146            "${target_name}__compile_incremental_resources"
3147
3148        action_with_pydeps(_incremental_compile_resources_target_name) {
3149          deps = [
3150            ":$_build_config_target",
3151            ":$_compile_resources_target",
3152            ":$_merge_manifest_target",
3153          ]
3154          script =
3155              "//build/android/incremental_install/generate_android_manifest.py"
3156          inputs = [
3157            _android_manifest,
3158            _build_config,
3159            _arsc_resources_path,
3160          ]
3161          outputs = [ _incremental_compiled_resources_path ]
3162
3163          args = [
3164            "--disable-isolated-processes",
3165            "--src-manifest",
3166            rebase_path(_android_manifest, root_build_dir),
3167            "--in-apk",
3168            rebase_path(_arsc_resources_path, root_build_dir),
3169            "--out-apk",
3170            rebase_path(_incremental_compiled_resources_path, root_build_dir),
3171            "--aapt2-path",
3172            rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
3173            "--android-sdk-jars=@FileArg($_rebased_build_config:android:sdk_jars)",
3174          ]
3175        }
3176      }
3177
3178      _create_apk_target = "${_template_name}__create"
3179      _final_deps += [ ":$_create_apk_target" ]
3180      package_apk("$_create_apk_target") {
3181        forward_variables_from(invoker,
3182                               [
3183                                 "expected_libs_and_assets",
3184                                 "expected_libs_and_assets_base",
3185                                 "native_lib_placeholders",
3186                                 "secondary_abi_loadable_modules",
3187                                 "secondary_native_lib_placeholders",
3188                                 "uncompress_dex",
3189                                 "uncompress_shared_libraries",
3190                                 "library_always_compress",
3191                                 "library_renames",
3192                               ])
3193
3194        if (defined(expected_libs_and_assets)) {
3195          build_config_dep = ":$_build_config_target"
3196          top_target_name = _template_name
3197        }
3198
3199        build_config = _build_config
3200        keystore_name = _keystore_name
3201        keystore_path = _keystore_path
3202        keystore_password = _keystore_password
3203        min_sdk_version = _min_sdk_version
3204        uncompress_shared_libraries = _uncompress_shared_libraries
3205
3206        deps = _deps + [ ":$_build_config_target" ]
3207
3208        if ((!_proguard_enabled || _incremental_apk) &&
3209            enable_jdk_library_desugaring) {
3210          _all_jdk_libs = "//build/android:all_jdk_libs"
3211          deps += [ _all_jdk_libs ]
3212          jdk_libs_dex = get_label_info(_all_jdk_libs, "target_out_dir") +
3213                         "/all_jdk_libs.l8.dex"
3214        }
3215
3216        if (_incremental_apk) {
3217          _dex_target = "//build/android/incremental_install:apk_dex"
3218
3219          deps += [
3220            ":${_incremental_compile_resources_target_name}",
3221            _dex_target,
3222          ]
3223
3224          dex_path = get_label_info(_dex_target, "target_out_dir") + "/apk.dex"
3225
3226          # All native libraries are side-loaded, so use a placeholder to force
3227          # the proper bitness for the app.
3228          _has_native_libs =
3229              defined(_native_libs_filearg) || _loadable_modules != []
3230          if (_has_native_libs && !defined(native_lib_placeholders)) {
3231            native_lib_placeholders = [ "libfix.crbug.384638.so" ]
3232          }
3233
3234          packaged_resources_path = _incremental_compiled_resources_path
3235          output_apk_path = _incremental_apk_path
3236        } else {
3237          loadable_modules = _loadable_modules
3238          deps += _all_native_libs_deps + [
3239                    ":$_merge_manifest_target",
3240                    ":$_compile_resources_target",
3241                  ]
3242
3243          if (defined(_final_dex_path)) {
3244            dex_path = _final_dex_path
3245            deps += [ _final_dex_target_dep ]
3246          }
3247
3248          if (_optimize_resources) {
3249            packaged_resources_path = _optimized_arsc_resources_path
3250          } else {
3251            packaged_resources_path = _arsc_resources_path
3252          }
3253
3254          if (defined(_native_libs_filearg)) {
3255            native_libs_filearg = _native_libs_filearg
3256            secondary_abi_native_libs_filearg = "@FileArg($_rebased_build_config:native:secondary_abi_libraries)"
3257          }
3258          output_apk_path = _final_apk_path
3259        }
3260      }
3261    }
3262
3263    if (_incremental_apk) {
3264      _write_installer_json_rule_name = "${_template_name}__incremental_json"
3265      action_with_pydeps(_write_installer_json_rule_name) {
3266        script = "//build/android/incremental_install/write_installer_json.py"
3267        deps = [ ":$_build_config_target" ] + _all_native_libs_deps
3268
3269        data = [ _incremental_install_json_path ]
3270        inputs = [ _build_config ]
3271        outputs = [ _incremental_install_json_path ]
3272
3273        _rebased_incremental_apk_path =
3274            rebase_path(_incremental_apk_path, root_build_dir)
3275        _rebased_incremental_install_json_path =
3276            rebase_path(_incremental_install_json_path, root_build_dir)
3277        args = [
3278          "--apk-path=$_rebased_incremental_apk_path",
3279          "--output-path=$_rebased_incremental_install_json_path",
3280          "--dex-file=@FileArg($_rebased_build_config:final_dex:all_dex_files)",
3281        ]
3282        if (_proguard_enabled) {
3283          args += [ "--show-proguard-warning" ]
3284        }
3285        if (defined(_native_libs_filearg)) {
3286          args += [ "--native-libs=$_native_libs_filearg" ]
3287          deps += [ _native_libs_filearg_dep ]
3288        }
3289        if (_loadable_modules != []) {
3290          _rebased_loadable_modules =
3291              rebase_path(_loadable_modules, root_build_dir)
3292          args += [ "--native-libs=$_rebased_loadable_modules" ]
3293        }
3294        if (_load_library_from_apk) {
3295          args += [ "--dont-even-try=Incremental builds do not work with load_library_from_apk. Try setting is_component_build=true in your GN args." ]
3296        }
3297      }
3298      _final_deps += [
3299        ":$_java_target",
3300        ":$_write_installer_json_rule_name",
3301      ]
3302    }
3303
3304    # Generate apk operation related script.
3305    if (!_is_bundle_module &&
3306        (!defined(invoker.create_apk_script) || invoker.create_apk_script)) {
3307      if (_uses_static_library) {
3308        _install_artifacts_target = "${target_name}__install_artifacts"
3309        _install_artifacts_json =
3310            "${target_gen_dir}/${target_name}.install_artifacts"
3311        generated_file(_install_artifacts_target) {
3312          output_conversion = "json"
3313          deps = [ invoker.static_library_provider ]
3314          outputs = [ _install_artifacts_json ]
3315          data_keys = [ "install_artifacts" ]
3316          rebase = root_build_dir
3317        }
3318      }
3319      _apk_operations_target_name = "${target_name}__apk_operations"
3320      action_with_pydeps(_apk_operations_target_name) {
3321        # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
3322        run_under_python2 = true
3323
3324        _generated_script = "$root_build_dir/bin/${invoker.target_name}"
3325        script = "//build/android/gyp/create_apk_operations_script.py"
3326        outputs = [ _generated_script ]
3327        data_deps = [ "//tools/android/md5sum" ]
3328        args = [
3329          "--script-output-path",
3330          rebase_path(_generated_script, root_build_dir),
3331          "--target-cpu=$target_cpu",
3332        ]
3333        if (defined(invoker.command_line_flags_file)) {
3334          args += [
3335            "--command-line-flags-file",
3336            invoker.command_line_flags_file,
3337          ]
3338        }
3339        if (_incremental_apk) {
3340          args += [
3341            "--incremental-install-json-path",
3342            rebase_path(_incremental_install_json_path, root_build_dir),
3343          ]
3344        } else {
3345          args += [
3346            "--apk-path",
3347            rebase_path(_final_apk_path, root_build_dir),
3348          ]
3349        }
3350        if (_uses_static_library) {
3351          deps = [ ":$_install_artifacts_target" ]
3352          _rebased_install_artifacts_json =
3353              rebase_path(_install_artifacts_json, root_build_dir)
3354          _static_library_apk_path =
3355              "@FileArg($_rebased_install_artifacts_json[])"
3356          args += [
3357            "--additional-apk",
3358            _static_library_apk_path,
3359          ]
3360        }
3361        if (!defined(data)) {
3362          data = []
3363        }
3364        if (_proguard_enabled && !_incremental_apk) {
3365          # Required by logcat command.
3366          data_deps += [ "//build/android/stacktrace:java_deobfuscate" ]
3367          data += [ "$_final_apk_path.mapping" ]
3368          args += [
3369            "--proguard-mapping-path",
3370            rebase_path("$_final_apk_path.mapping", root_build_dir),
3371          ]
3372        }
3373      }
3374      _final_deps += [ ":$_apk_operations_target_name" ]
3375    }
3376
3377    _enable_lint = defined(invoker.enable_lint) && invoker.enable_lint &&
3378                   !disable_android_lint
3379    if (_enable_lint) {
3380      android_lint("${target_name}__lint") {
3381        forward_variables_from(invoker,
3382                               [
3383                                 "lint_baseline_file",
3384                                 "lint_suppressions_file",
3385                                 "min_sdk_version",
3386                               ])
3387        build_config = _build_config
3388        build_config_dep = ":$_build_config_target"
3389        deps = [ ":$_java_target" ]
3390        if (defined(invoker.lint_suppressions_dep)) {
3391          deps += [ invoker.lint_suppressions_dep ]
3392        }
3393        if (defined(invoker.lint_min_sdk_version)) {
3394          min_sdk_version = invoker.lint_min_sdk_version
3395        }
3396      }
3397    } else {
3398      not_needed(invoker,
3399                 [
3400                   "lint_baseline_file",
3401                   "lint_min_sdk_version",
3402                   "lint_suppressions_dep",
3403                   "lint_suppressions_file",
3404                 ])
3405    }
3406
3407    group(target_name) {
3408      forward_variables_from(invoker,
3409                             [
3410                               "assert_no_deps",
3411                               "data",
3412                               "data_deps",
3413                               "metadata",
3414                             ])
3415
3416      # Generate apk related operations at runtime.
3417      public_deps = _final_deps
3418
3419      if (!defined(data_deps)) {
3420        data_deps = []
3421      }
3422
3423      # Include unstripped native libraries so tests can symbolize stacks.
3424      data_deps += _all_native_libs_deps
3425
3426      if (_enable_lint) {
3427        data_deps += [ ":${target_name}__lint" ]
3428      }
3429
3430      if (_incremental_apk) {
3431        # device/commands is used by the installer script to push files via .zip.
3432        data_deps += [ "//build/android/pylib/device/commands" ]
3433      }
3434      if (_uses_static_library) {
3435        data_deps += [ invoker.static_library_provider ]
3436      }
3437    }
3438  }
3439
3440  # Declare an Android APK target
3441  #
3442  # This target creates an Android APK containing java code, resources, assets,
3443  # and (possibly) native libraries.
3444  #
3445  # Supports all variables of android_apk_or_module(), plus:
3446  #   apk_name: Name for final apk.
3447  #   final_apk_path: (Optional) path to output APK.
3448  #
3449  # Example
3450  #   android_apk("foo_apk") {
3451  #     android_manifest = "AndroidManifest.xml"
3452  #     sources = [
3453  #       "android/org/chromium/foo/FooApplication.java",
3454  #       "android/org/chromium/foo/FooActivity.java",
3455  #     ]
3456  #     deps = [
3457  #       ":foo_support_java"
3458  #       ":foo_resources"
3459  #     ]
3460  #     srcjar_deps = [
3461  #       ":foo_generated_enum"
3462  #     ]
3463  #     shared_libraries = [
3464  #       ":my_shared_lib",
3465  #     ]
3466  #   }
3467  template("android_apk") {
3468    # TODO(crbug.com/1042017): Remove.
3469    not_needed(invoker, [ "no_build_hooks" ])
3470    android_apk_or_module(target_name) {
3471      forward_variables_from(invoker,
3472                             [
3473                               "aapt_locale_allowlist",
3474                               "additional_jar_files",
3475                               "alternative_android_sdk_dep",
3476                               "android_manifest",
3477                               "android_manifest_dep",
3478                               "annotation_processor_deps",
3479                               "apk_under_test",
3480                               "app_as_shared_lib",
3481                               "assert_no_deps",
3482                               "bundles_supported",
3483                               "chromium_code",
3484                               "command_line_flags_file",
3485                               "create_apk_script",
3486                               "data",
3487                               "data_deps",
3488                               "deps",
3489                               "dexlayout_profile",
3490                               "disable_r8_outlining",
3491                               "dist_ijar_path",
3492                               "enable_lint",
3493                               "enable_jetify",
3494                               "enable_multidex",
3495                               "enable_native_mocks",
3496                               "enable_proguard_checks",
3497                               "enforce_resource_overlays_in_tests",
3498                               "expected_android_manifest",
3499                               "expected_android_manifest_base",
3500                               "expected_libs_and_assets",
3501                               "expected_libs_and_assets_base",
3502                               "generate_buildconfig_java",
3503                               "generate_final_jni",
3504                               "input_jars_paths",
3505                               "use_modern_linker",
3506                               "jacoco_never_instrument",
3507                               "javac_args",
3508                               "jni_registration_header",
3509                               "jni_sources_exclusions",
3510                               "keystore_name",
3511                               "keystore_password",
3512                               "keystore_path",
3513                               "lint_baseline_file",
3514                               "lint_min_sdk_version",
3515                               "lint_suppressions_dep",
3516                               "lint_suppressions_file",
3517                               "load_library_from_apk",
3518                               "loadable_modules",
3519                               "manifest_package",
3520                               "max_sdk_version",
3521                               "product_config_java_packages",
3522                               "main_component_library",
3523                               "min_sdk_version",
3524                               "native_lib_placeholders",
3525                               "native_lib_version_arg",
3526                               "native_lib_version_rule",
3527                               "negative_main_dex_globs",
3528                               "never_incremental",
3529                               "no_xml_namespaces",
3530                               "png_to_webp",
3531                               "post_process_package_resources_script",
3532                               "processor_args_javac",
3533                               "product_version_resources_dep",
3534                               "proguard_configs",
3535                               "proguard_enabled",
3536                               "r_java_root_package_name",
3537                               "resource_exclusion_exceptions",
3538                               "resource_exclusion_regex",
3539                               "resource_ids_provider_dep",
3540                               "resource_values_filter_rules",
3541                               "resources_config_paths",
3542                               "require_native_mocks",
3543                               "secondary_abi_loadable_modules",
3544                               "secondary_abi_shared_libraries",
3545                               "secondary_native_lib_placeholders",
3546                               "shared_libraries",
3547                               "shared_resources",
3548                               "shared_resources_allowlist_locales",
3549                               "shared_resources_allowlist_target",
3550                               "short_resource_paths",
3551                               "sources",
3552                               "srcjar_deps",
3553                               "static_library_dependent_targets",
3554                               "static_library_provider",
3555                               "static_library_synchronized_proguard",
3556                               "strip_resource_names",
3557                               "support_zh_hk",
3558                               "target_sdk_version",
3559                               "testonly",
3560                               "uncompress_dex",
3561                               "uncompress_shared_libraries",
3562                               "library_always_compress",
3563                               "library_renames",
3564                               "use_chromium_linker",
3565                               "version_code",
3566                               "version_name",
3567                             ])
3568      is_bundle_module = false
3569      name = invoker.apk_name
3570      if (defined(invoker.final_apk_path)) {
3571        final_apk_path = invoker.final_apk_path
3572      } else {
3573        final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk"
3574      }
3575      metadata = {
3576        install_artifacts = [ final_apk_path ]
3577      }
3578      if (defined(invoker.static_library_provider)) {
3579        metadata.install_artifacts_barrier = []
3580      }
3581    }
3582  }
3583
3584  # Declare an Android app bundle module target.
3585  #
3586  # The module can be used for an android_apk_or_module().
3587  #
3588  # Supports all variables of android_library(), plus:
3589  #   module_name: Name of the module.
3590  #   is_base_module: If defined and true, indicates that this is the bundle's
3591  #     base module (optional).
3592  #   base_module_target: Base module target of the bundle this module will be
3593  #     added to (optional). Can only be specified for non-base modules.
3594  #   bundle_target: Bundle target that this module belongs to (optional).
3595  #     Can only be specified for base modules.
3596  template("android_app_bundle_module") {
3597    _is_base_module = defined(invoker.is_base_module) && invoker.is_base_module
3598
3599    if (_is_base_module) {
3600      assert(!defined(invoker.base_module_target))
3601    } else {
3602      assert(!defined(invoker.app_as_shared_lib))
3603      assert(!defined(invoker.shared_resources))
3604      assert(!defined(invoker.shared_resources_allowlist_target))
3605      assert(!defined(invoker.shared_resources_allowlist_locales))
3606      assert(defined(invoker.base_module_target))
3607      assert(!defined(invoker.bundle_target))
3608    }
3609
3610    # TODO(tiborg): We have several flags that are necessary for workarounds
3611    # that come from the fact that the resources get compiled in the bundle
3612    # module target, but bundle modules have to have certain flags in
3613    # common or bundle modules have to know information about the base module.
3614    # Those flags include version_code, version_name, and base_module_target.
3615    # It would be better to move the resource compile target into the bundle
3616    # target. Doing so would keep the bundle modules independent from the bundle
3617    # and potentially reuse the same bundle modules for multiple bundles.
3618    android_apk_or_module(target_name) {
3619      forward_variables_from(invoker,
3620                             [
3621                               "aapt_locale_allowlist",
3622                               "additional_jar_files",
3623                               "alternative_android_sdk_dep",
3624                               "android_manifest",
3625                               "android_manifest_dep",
3626                               "annotation_processor_deps",
3627                               "app_as_shared_lib",
3628                               "assert_no_deps",
3629                               "base_module_target",
3630                               "bundle_target",
3631                               "chromium_code",
3632                               "data",
3633                               "data_deps",
3634                               "deps",
3635                               "enable_multidex",
3636                               "expected_android_manifest",
3637                               "expected_android_manifest_base",
3638                               "generate_buildconfig_java",
3639                               "generate_final_jni",
3640                               "input_jars_paths",
3641                               "isolated_splits_enabled",
3642                               "is_base_module",
3643                               "jacoco_never_instrument",
3644                               "jar_excluded_patterns",
3645                               "javac_args",
3646                               "jni_registration_header",
3647                               "jni_sources_exclusions",
3648                               "load_library_from_apk",
3649                               "loadable_modules",
3650                               "product_config_java_packages",
3651                               "manifest_package",
3652                               "max_sdk_version",
3653                               "min_sdk_version",
3654                               "native_lib_placeholders",
3655                               "native_lib_version_arg",
3656                               "native_lib_version_rule",
3657                               "negative_main_dex_globs",
3658                               "no_xml_namespaces",
3659                               "package_id",
3660                               "package_name",
3661                               "png_to_webp",
3662                               "processor_args_javac",
3663                               "product_version_resources_dep",
3664                               "proguard_configs",
3665                               "proguard_enabled",
3666                               "resource_exclusion_exceptions",
3667                               "resource_exclusion_regex",
3668                               "resource_ids_provider_dep",
3669                               "resource_values_filter_rules",
3670                               "resources_config_paths",
3671                               "secondary_abi_loadable_modules",
3672                               "secondary_abi_shared_libraries",
3673                               "secondary_native_lib_placeholders",
3674                               "shared_libraries",
3675                               "shared_resources",
3676                               "shared_resources_allowlist_locales",
3677                               "shared_resources_allowlist_target",
3678                               "short_resource_paths",
3679                               "srcjar_deps",
3680                               "static_library_provider",
3681                               "static_library_synchronized_proguard",
3682                               "strip_resource_names",
3683                               "support_zh_hk",
3684                               "target_sdk_version",
3685                               "testonly",
3686                               "uncompress_shared_libraries",
3687                               "library_always_compress",
3688                               "library_renames",
3689                               "use_chromium_linker",
3690                               "use_modern_linker",
3691                               "uses_split",
3692                               "version_code",
3693                               "version_name",
3694                             ])
3695      is_bundle_module = true
3696      generate_buildconfig_java = _is_base_module
3697    }
3698  }
3699
3700  # Declare an Android instrumentation test runner.
3701  #
3702  # This target creates a wrapper script to run Android instrumentation tests.
3703  #
3704  # Arguments:
3705  #   android_test_apk: The target containing the tests.
3706  #   android_test_apk_name: The apk_name in android_test_apk
3707  #
3708  #   The following args are optional:
3709  #   apk_under_test: The target being tested.
3710  #   additional_apks: Additional targets to install on device.
3711  #   data: List of runtime data file dependencies.
3712  #   data_deps: List of non-linked dependencies.
3713  #   deps: List of private dependencies.
3714  #   extra_args: Extra arguments set for test runner.
3715  #   ignore_all_data_deps: Don't build data_deps and additional_apks.
3716  #   modules: Extra dynamic feature modules to install for test target. Can
3717  #     only be used if |apk_under_test| is an Android app bundle.
3718  #   fake_modules: Similar to |modules| but fake installed instead.
3719  #   never_incremental: Disable incremental builds.
3720  #   proguard_enabled: Enable proguard
3721  #   public_deps: List of public dependencies
3722  #
3723  # Example
3724  #   instrumentation_test_runner("foo_test_for_bar") {
3725  #     android_test_apk: ":foo"
3726  #     android_test_apk_name: "Foo"
3727  #     apk_under_test: ":bar"
3728  #   }
3729  template("instrumentation_test_runner") {
3730    test_runner_script(target_name) {
3731      forward_variables_from(invoker,
3732                             [
3733                               "additional_apks",
3734                               "additional_locales",
3735                               "apk_under_test",
3736                               "data",
3737                               "data_deps",
3738                               "deps",
3739                               "extra_args",
3740                               "fake_modules",
3741                               "ignore_all_data_deps",
3742                               "modules",
3743                               "proguard_enabled",
3744                               "public_deps",
3745                               "use_webview_provider",
3746                             ])
3747      test_name = invoker.target_name
3748      test_type = "instrumentation"
3749      _apk_target_name = get_label_info(invoker.android_test_apk, "name")
3750      apk_target = ":$_apk_target_name"
3751      test_jar = "$root_build_dir/test.lib.java/" +
3752                 invoker.android_test_apk_name + ".jar"
3753      incremental_apk = !(defined(invoker.never_incremental) &&
3754                          invoker.never_incremental) && incremental_install
3755
3756      public_deps = [
3757        ":$_apk_target_name",
3758
3759        # Required by test runner to enumerate test list.
3760        ":${_apk_target_name}_dist_ijar",
3761      ]
3762      if (defined(invoker.apk_under_test)) {
3763        public_deps += [ invoker.apk_under_test ]
3764      }
3765      if (defined(invoker.additional_apks)) {
3766        public_deps += invoker.additional_apks
3767      }
3768    }
3769  }
3770
3771  # Declare an Android instrumentation test apk
3772  #
3773  # This target creates an Android instrumentation test apk.
3774  #
3775  # Supports all variables of android_apk(), plus:
3776  #   apk_under_test: The apk being tested (optional).
3777  #
3778  # Example
3779  #   android_test_apk("foo_test_apk") {
3780  #     android_manifest = "AndroidManifest.xml"
3781  #     apk_name = "FooTest"
3782  #     apk_under_test = "Foo"
3783  #     sources = [
3784  #       "android/org/chromium/foo/FooTestCase.java",
3785  #       "android/org/chromium/foo/FooExampleTest.java",
3786  #     ]
3787  #     deps = [
3788  #       ":foo_test_support_java"
3789  #     ]
3790  #   }
3791  template("android_test_apk") {
3792    android_apk(target_name) {
3793      testonly = true
3794      deps = [ "//testing/android/broker:broker_java" ]
3795      if (defined(invoker.deps)) {
3796        deps += invoker.deps
3797      }
3798      data_deps = [
3799        # Ensure unstripped libraries are included in runtime deps so that
3800        # symbolization can be done.
3801        ":${target_name}__secondary_abi_shared_library_list",
3802        ":${target_name}__shared_library_list",
3803        "//build/android/pylib/device/commands",
3804        "//tools/android/forwarder2",
3805      ]
3806      if (defined(invoker.data_deps)) {
3807        data_deps += invoker.data_deps
3808      }
3809      if (defined(invoker.apk_under_test)) {
3810        data_deps += [ invoker.apk_under_test ]
3811      } else {
3812        enable_native_mocks = true
3813      }
3814
3815      if (defined(invoker.apk_under_test)) {
3816        _under_test_label =
3817            get_label_info(invoker.apk_under_test, "label_no_toolchain")
3818        data_deps += [
3819          "${_under_test_label}__secondary_abi_shared_library_list",
3820          "${_under_test_label}__shared_library_list",
3821        ]
3822      }
3823
3824      if (defined(invoker.additional_apks)) {
3825        data_deps += invoker.additional_apks
3826      }
3827      if (defined(invoker.use_webview_provider)) {
3828        data_deps += [ invoker.use_webview_provider ]
3829      }
3830
3831      data = []
3832      if (defined(invoker.data)) {
3833        data += invoker.data
3834      }
3835      if (defined(invoker.proguard_enabled) && invoker.proguard_enabled &&
3836          !incremental_install) {
3837        # When ProGuard is on, we use ProGuard to combine the under test java
3838        # code and the test java code. This is to allow us to apply all ProGuard
3839        # optimizations that we ship with, but not have them break tests. The
3840        # apk under test will still have the same resources, assets, and
3841        # manifest, all of which are the ones used in the tests.
3842        proguard_configs = [ "//testing/android/proguard_for_test.flags" ]
3843        if (defined(invoker.proguard_configs)) {
3844          proguard_configs += invoker.proguard_configs
3845        }
3846        enable_proguard_checks = false
3847        if (defined(invoker.final_apk_path)) {
3848          _final_apk_path = final_apk_path
3849        } else {
3850          _final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk"
3851        }
3852        data += [ "$_final_apk_path.mapping" ]
3853      }
3854
3855      dist_ijar_path = "$root_build_dir/test.lib.java/${invoker.apk_name}.jar"
3856      create_apk_script = false
3857
3858      forward_variables_from(invoker,
3859                             "*",
3860                             [
3861                               "data",
3862                               "data_deps",
3863                               "deps",
3864                               "proguard_configs",
3865                             ])
3866    }
3867  }
3868
3869  # Declare an Android instrumentation test apk with wrapper script.
3870  #
3871  # This target creates an Android instrumentation test apk with wrapper script
3872  # to run the test.
3873  #
3874  # Supports all variables of android_test_apk.
3875  template("instrumentation_test_apk") {
3876    assert(defined(invoker.apk_name))
3877    _apk_target_name = "${target_name}__test_apk"
3878    android_test_apk(_apk_target_name) {
3879      forward_variables_from(invoker, "*")
3880    }
3881    instrumentation_test_runner(target_name) {
3882      forward_variables_from(invoker,
3883                             [
3884                               "additional_apks",
3885                               "apk_under_test",
3886                               "data",
3887                               "data_deps",
3888                               "deps",
3889                               "extra_args",
3890                               "ignore_all_data_deps",
3891                               "modules",
3892                               "never_incremental",
3893                               "proguard_enabled",
3894                               "public_deps",
3895                               "use_webview_provider",
3896                             ])
3897      android_test_apk = ":${_apk_target_name}"
3898      android_test_apk_name = invoker.apk_name
3899    }
3900  }
3901
3902  # Declare an Android gtest apk
3903  #
3904  # This target creates an Android apk for running gtest-based unittests.
3905  #
3906  # Variables
3907  #   deps: Specifies the dependencies of this target. These will be passed to
3908  #     the underlying android_apk invocation and should include the java and
3909  #     resource dependencies of the apk.
3910  #   shared_library: shared_library target that contains the unit tests.
3911  #   apk_name: The name of the produced apk. If unspecified, it uses the name
3912  #             of the shared_library target suffixed with "_apk"
3913  #   use_default_launcher: Whether the default activity (NativeUnitTestActivity)
3914  #     should be used for launching tests.
3915  #   use_native_activity: Test implements ANativeActivity_onCreate().
3916  #
3917  # Example
3918  #   unittest_apk("foo_unittests_apk") {
3919  #     deps = [ ":foo_java", ":foo_resources" ]
3920  #     shared_library = ":foo_unittests"
3921  #   }
3922  template("unittest_apk") {
3923    _use_native_activity =
3924        defined(invoker.use_native_activity) && invoker.use_native_activity
3925    _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml"
3926    assert(invoker.shared_library != "")
3927
3928    # This trivial assert is needed in case android_manifest is defined,
3929    # as otherwise _use_native_activity and _android_manifest would not be used.
3930    assert(_use_native_activity != "" && _android_manifest != "")
3931
3932    if (!defined(invoker.android_manifest)) {
3933      jinja_template("${target_name}_manifest") {
3934        _native_library_name = get_label_info(invoker.shared_library, "name")
3935        input = "//testing/android/native_test/java/AndroidManifest.xml.jinja2"
3936        output = _android_manifest
3937        variables = [
3938          "is_component_build=${is_component_build}",
3939          "native_library_name=${_native_library_name}",
3940          "use_native_activity=${_use_native_activity}",
3941        ]
3942      }
3943    }
3944
3945    android_apk(target_name) {
3946      data_deps = []
3947      forward_variables_from(invoker, "*")
3948      testonly = true
3949      create_apk_script = false
3950      enable_native_mocks = true
3951
3952      # TODO(crbug.com/1099849): Figure out why angle tests fail to launch
3953      #     with newer target_sdk_version.
3954      if (!defined(invoker.target_sdk_version) && _use_native_activity) {
3955        target_sdk_version = 24
3956      }
3957
3958      assert(!defined(invoker.proguard_enabled) || !invoker.proguard_enabled ||
3959             invoker.proguard_configs != [])
3960
3961      if (!defined(apk_name)) {
3962        apk_name = get_label_info(invoker.shared_library, "name")
3963      }
3964
3965      if (!defined(android_manifest)) {
3966        android_manifest_dep = ":${target_name}_manifest"
3967        android_manifest = _android_manifest
3968      }
3969
3970      final_apk_path = "$root_build_dir/${apk_name}_apk/${apk_name}-debug.apk"
3971
3972      if (!defined(use_default_launcher) || use_default_launcher) {
3973        deps += [ "//testing/android/native_test:native_test_java" ]
3974      }
3975      shared_libraries = [ invoker.shared_library ]
3976      deps += [
3977        ":${target_name}__secondary_abi_shared_library_list",
3978        ":${target_name}__shared_library_list",
3979        "//base:base_java",
3980        "//testing/android/reporter:reporter_java",
3981      ]
3982      data_deps += [ "//build/android/pylib/device/commands" ]
3983      if (host_os == "linux") {
3984        data_deps += [ "//tools/android/forwarder2" ]
3985      }
3986    }
3987  }
3988
3989  # Generate .java files from .aidl files.
3990  #
3991  # This target will store the .java files in a srcjar and should be included in
3992  # an android_library or android_apk's srcjar_deps.
3993  #
3994  # Variables
3995  #   sources: Paths to .aidl files to compile.
3996  #   import_include: Path to directory containing .java files imported by the
3997  #     .aidl files.
3998  #   interface_file: Preprocessed aidl file to import.
3999  #
4000  # Example
4001  #   android_aidl("foo_aidl") {
4002  #     import_include = "java/src"
4003  #     sources = [
4004  #       "java/src/com/foo/bar/FooBarService.aidl",
4005  #       "java/src/com/foo/bar/FooBarServiceCallback.aidl",
4006  #     ]
4007  #   }
4008  template("android_aidl") {
4009    action_with_pydeps(target_name) {
4010      forward_variables_from(invoker, [ "testonly" ])
4011
4012      script = "//build/android/gyp/aidl.py"
4013      sources = invoker.sources
4014
4015      _srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
4016      _aidl_path = "${android_sdk_build_tools}/aidl"
4017      _framework_aidl = "$android_sdk/framework.aidl"
4018      _imports = [ _framework_aidl ]
4019      if (defined(invoker.interface_file)) {
4020        assert(invoker.interface_file != "")
4021        _imports += [ invoker.interface_file ]
4022      }
4023
4024      inputs = [ _aidl_path ] + _imports
4025
4026      outputs = [ _srcjar_path ]
4027      _rebased_imports = rebase_path(_imports, root_build_dir)
4028      args = [
4029        "--aidl-path",
4030        rebase_path(_aidl_path, root_build_dir),
4031        "--imports=$_rebased_imports",
4032        "--srcjar",
4033        rebase_path(_srcjar_path, root_build_dir),
4034      ]
4035      if (defined(invoker.import_include) && invoker.import_include != []) {
4036        # TODO(cjhopman): aidl supports creating a depfile. We should be able to
4037        # switch to constructing a depfile for the overall action from that
4038        # instead of having all the .java files in the include paths as inputs.
4039        _rebased_import_paths = []
4040        foreach(_import_path, invoker.import_include) {
4041          _rebased_import_path = []
4042          _rebased_import_path = [ rebase_path(_import_path, root_build_dir) ]
4043          _rebased_import_paths += _rebased_import_path
4044          _java_files_build_rel = []
4045          _java_files_build_rel =
4046              exec_script("//build/android/gyp/find.py",
4047                          [ "--pattern=*.java" ] + _rebased_import_path,
4048                          "list lines")
4049          inputs += rebase_path(_java_files_build_rel, ".", root_build_dir)
4050        }
4051        args += [ "--includes=$_rebased_import_paths" ]
4052      }
4053      args += rebase_path(sources, root_build_dir)
4054    }
4055  }
4056
4057  # Compile a protocol buffer to java.
4058  #
4059  # This generates java files from protocol buffers and creates an Android library
4060  # containing the classes.
4061  #
4062  # Variables
4063  #   sources (required)
4064  #       Paths to .proto files to compile.
4065  #
4066  #   proto_path (required)
4067  #       Root directory of .proto files.
4068  #
4069  #   deps (optional)
4070  #       Additional dependencies. Passed through to both the action and the
4071  #       android_library targets.
4072  #
4073  #   import_dirs (optional)
4074  #       A list of extra import directories to be passed to protoc compiler.
4075  #       WARNING: This circumvents proto checkdeps, and should only be used
4076  #       when needed, typically when proto files cannot cleanly import through
4077  #       absolute paths, such as for third_party or generated .proto files.
4078  #       http://crbug.com/691451 tracks fixing this.
4079  #
4080  # Example:
4081  #  proto_java_library("foo_proto_java") {
4082  #    proto_path = "src/foo"
4083  #    sources = [ "$proto_path/foo.proto" ]
4084  #  }
4085  template("proto_java_library") {
4086    forward_variables_from(invoker, [ "testonly" ])
4087
4088    _template_name = target_name
4089
4090    action_with_pydeps("${_template_name}__protoc_java") {
4091      # The suffix "__protoc_java.srcjar" is used by SuperSize to identify
4092      # protobuf symbols.
4093      _srcjar_path = "$target_gen_dir/$target_name.srcjar"
4094      script = "//build/protoc_java.py"
4095
4096      deps = []
4097      if (defined(invoker.deps)) {
4098        deps += invoker.deps
4099      }
4100
4101      sources = invoker.sources
4102      depfile = "$target_gen_dir/$target_name.d"
4103      outputs = [ _srcjar_path ]
4104      args = [
4105               "--depfile",
4106               rebase_path(depfile, root_build_dir),
4107               "--protoc",
4108               rebase_path(android_protoc_bin, root_build_dir),
4109               "--proto-path",
4110               rebase_path(invoker.proto_path, root_build_dir),
4111               "--srcjar",
4112               rebase_path(_srcjar_path, root_build_dir),
4113             ] + rebase_path(sources, root_build_dir)
4114
4115      if (defined(invoker.import_dirs)) {
4116        foreach(_import_dir, invoker.import_dirs) {
4117          args += [
4118            "--import-dir",
4119            rebase_path(_import_dir, root_build_dir),
4120          ]
4121        }
4122      }
4123    }
4124
4125    android_library(target_name) {
4126      chromium_code = false
4127      sources = []
4128      srcjar_deps = [ ":${_template_name}__protoc_java" ]
4129      deps = [ "//third_party/android_deps:protobuf_lite_runtime_java" ]
4130      if (defined(invoker.deps)) {
4131        deps += invoker.deps
4132      }
4133    }
4134  }
4135
4136  # Declare an Android library target for a prebuilt AAR.
4137  #
4138  # This target creates an Android library containing java code and Android
4139  # resources. For libraries without resources, it will not generate
4140  # corresponding android_resources targets.
4141  #
4142  # To avoid slowing down "gn gen", an associated .info file must be committed
4143  # along with the .aar file. In order to create this file, define the target
4144  # and then run once with the gn arg "update_android_aar_prebuilts = true".
4145  #
4146  # Variables
4147  #   aar_path: Path to the AAR.
4148  #   info_path: Path to the .aar.info file (generated via
4149  #       update_android_aar_prebuilts GN arg).
4150  #   proguard_configs: List of proguard configs to use in final apk step for
4151  #       any apk that depends on this library.
4152  #   ignore_aidl: Whether to ignore .aidl files found with the .aar.
4153  #   ignore_assets: Whether to ignore assets found in the .aar.
4154  #   ignore_manifest: Whether to ignore creating manifest.
4155  #   ignore_native_libraries: Whether to ignore .so files found in the .aar.
4156  #       See also extract_native_libraries.
4157  #   ignore_proguard_configs: Whether to ignore proguard configs.
4158  #   ignore_info_updates: Whether to ignore the info file when
4159  #       update_android_aar_prebuilts gn arg is true. However, the info file
4160  #       will still be verified regardless of the value of this flag.
4161  #   strip_resources: Whether to ignore android resources found in the .aar.
4162  #   custom_package: Java package for generated R.java files.
4163  #   extract_native_libraries: Whether to extract .so files found in the .aar.
4164  #       If the file contains .so, either extract_native_libraries or
4165  #       ignore_native_libraries must be set.
4166  #   create_srcjar: If false, does not create an R.java file.
4167  #   TODO(jbudorick@): remove this arguments after crbug.com/522043 is fixed.
4168  #   requires_android: Whether this target can only be used for compiling
4169  #       Android related targets.
4170  #
4171  # Example
4172  #   android_aar_prebuilt("foo_java") {
4173  #     aar_path = "foo.aar"
4174  #   }
4175  template("android_aar_prebuilt") {
4176    _info_path = "$target_name.info"
4177    if (defined(invoker.info_path)) {
4178      _info_path = invoker.info_path
4179    }
4180    _output_path = "${target_out_dir}/${target_name}"
4181    _target_name_without_java_or_junit =
4182        string_replace(string_replace(target_name, "_java", ""), "_junit", "")
4183
4184    # This unpack target is a python action, not a valid java target. Since the
4185    # java targets below depend on it, its name must not match the java patterns
4186    # in internal_rules.gni.
4187    _unpack_target_name = "${_target_name_without_java_or_junit}__unpack_aar"
4188    _ignore_aidl = defined(invoker.ignore_aidl) && invoker.ignore_aidl
4189    _ignore_assets = defined(invoker.ignore_assets) && invoker.ignore_assets
4190    _ignore_manifest =
4191        defined(invoker.ignore_manifest) && invoker.ignore_manifest
4192    _ignore_native_libraries = defined(invoker.ignore_native_libraries) &&
4193                               invoker.ignore_native_libraries
4194    _ignore_proguard_configs = defined(invoker.ignore_proguard_configs) &&
4195                               invoker.ignore_proguard_configs
4196    _extract_native_libraries = defined(invoker.extract_native_libraries) &&
4197                                invoker.extract_native_libraries
4198    _strip_resources =
4199        defined(invoker.strip_resources) && invoker.strip_resources
4200
4201    # Allow 'resource_overlay' parameter even if there are no resources in order
4202    # to keep the logic for generated 'android_aar_prebuilt' rules simple.
4203    not_needed(invoker, [ "resource_overlay" ])
4204
4205    _ignore_info_updates =
4206        defined(invoker.ignore_info_updates) && invoker.ignore_info_updates
4207
4208    # Scan the AAR file and determine the resources and jar files.
4209    # Some libraries might not have resources; others might have two jars.
4210    if (!_ignore_info_updates && update_android_aar_prebuilts) {
4211      print("Writing " + rebase_path(_info_path, "//"))
4212      exec_script("//build/android/gyp/aar.py",
4213                  [
4214                    "list",
4215                    rebase_path(invoker.aar_path, root_build_dir),
4216                    "--output",
4217                    rebase_path(_info_path, root_build_dir),
4218                  ])
4219    }
4220
4221    # If "gn gen" is failing on the following line, you need to generate an
4222    # .info file for your new target by running:
4223    #   gn gen --args='target_os="android" update_android_aar_prebuilts=true' out/tmp
4224    #   rm -r out/tmp
4225    _scanned_files = read_file(_info_path, "scope")
4226
4227    _use_scanned_assets = !_ignore_assets && _scanned_files.assets != []
4228
4229    assert(_ignore_aidl || _scanned_files.aidl == [],
4230           "android_aar_prebuilt() aidl not yet supported." +
4231               " Implement or use ignore_aidl = true." +
4232               " http://crbug.com/644439")
4233    assert(
4234        !_scanned_files.has_native_libraries ||
4235            (_ignore_native_libraries || _extract_native_libraries),
4236        "android_aar_prebuilt() contains .so files." +
4237            " Please set ignore_native_libraries or extract_native_libraries.")
4238    assert(
4239        !(_ignore_native_libraries && _extract_native_libraries),
4240        "ignore_native_libraries and extract_native_libraries cannot both be set.")
4241    assert(!_scanned_files.has_native_libraries ||
4242           _scanned_files.native_libraries != [])
4243    assert(_scanned_files.has_classes_jar || _scanned_files.subjars == [])
4244
4245    action_with_pydeps(_unpack_target_name) {
4246      # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
4247      run_under_python2 = true
4248
4249      script = "//build/android/gyp/aar.py"  # Unzips the AAR
4250      args = [
4251        "extract",
4252        rebase_path(invoker.aar_path, root_build_dir),
4253        "--output-dir",
4254        rebase_path(_output_path, root_build_dir),
4255        "--assert-info-file",
4256        rebase_path(_info_path, root_build_dir),
4257      ]
4258      if (_strip_resources) {
4259        args += [ "--ignore-resources" ]
4260      }
4261      inputs = [ invoker.aar_path ]
4262      outputs = [ "${_output_path}/AndroidManifest.xml" ]
4263      if (!_strip_resources && _scanned_files.has_r_text_file) {
4264        # Certain packages, in particular Play Services have no R.txt even
4265        # though its presence is mandated by AAR spec. Such packages cause
4266        # spurious rebuilds if this output is specified unconditionally.
4267        outputs += [ "${_output_path}/R.txt" ]
4268      }
4269
4270      if (!_strip_resources && _scanned_files.resources != []) {
4271        outputs += get_path_info(
4272                rebase_path(_scanned_files.resources, "", _output_path),
4273                "abspath")
4274      }
4275      if (_scanned_files.has_classes_jar) {
4276        outputs += [ "${_output_path}/classes.jar" ]
4277      }
4278      outputs +=
4279          get_path_info(rebase_path(_scanned_files.subjars, "", _output_path),
4280                        "abspath")
4281      if (!_ignore_proguard_configs) {
4282        if (_scanned_files.has_proguard_flags) {
4283          outputs += [ "${_output_path}/proguard.txt" ]
4284        }
4285      }
4286
4287      if (_extract_native_libraries && _scanned_files.has_native_libraries) {
4288        outputs += get_path_info(
4289                rebase_path(_scanned_files.native_libraries, "", _output_path),
4290                "abspath")
4291      }
4292      if (_use_scanned_assets) {
4293        outputs +=
4294            get_path_info(rebase_path(_scanned_files.assets, "", _output_path),
4295                          "abspath")
4296      }
4297    }
4298
4299    _has_unignored_resources =
4300        !_strip_resources &&
4301        (_scanned_files.resources != [] || _scanned_files.has_r_text_file)
4302
4303    _should_process_manifest =
4304        !_ignore_manifest && !_scanned_files.is_manifest_empty
4305
4306    # Create the android_resources target for resources.
4307    if (_has_unignored_resources || _should_process_manifest) {
4308      _res_target_name = "${target_name}__resources"
4309      android_resources(_res_target_name) {
4310        forward_variables_from(invoker,
4311                               [
4312                                 "custom_package",
4313                                 "create_srcjar",
4314                                 "deps",
4315                                 "resource_overlay",
4316                                 "testonly",
4317                                 "strip_drawables",
4318                               ])
4319        if (!defined(deps)) {
4320          deps = []
4321        }
4322        deps += [ ":$_unpack_target_name" ]
4323        if (_should_process_manifest) {
4324          android_manifest_dep = ":$_unpack_target_name"
4325          android_manifest = "${_output_path}/AndroidManifest.xml"
4326        } else if (defined(_scanned_files.manifest_package) &&
4327                   !defined(custom_package)) {
4328          custom_package = _scanned_files.manifest_package
4329        }
4330
4331        sources = []
4332        if (!_strip_resources) {
4333          sources = rebase_path(_scanned_files.resources, "", _output_path)
4334        }
4335        if (!_strip_resources && _scanned_files.has_r_text_file) {
4336          r_text_file = "${_output_path}/R.txt"
4337        }
4338
4339        # This is so we do not fail when different prebuilts have resources in
4340        # the same package. android_library targets that require resources from
4341        # prebuilts must add a resources_package gn flag to their target that
4342        # would generate a fake R.java for all their dependencies. All
4343        # android_library and android_resources targets will be migrated to
4344        # this new way soon (tm) https://crbug.com/1073476
4345        create_srcjar = false
4346      }
4347    } else if (defined(invoker.strip_drawables)) {
4348      not_needed(invoker, [ "strip_drawables" ])
4349    }
4350
4351    if (_ignore_manifest) {
4352      # Having this available can be useful for DFMs that depend on AARs. It
4353      # provides a way to have manifest entries go into the base split while
4354      # the code goes into a DFM.
4355      java_group("${target_name}__ignored_manifest") {
4356        forward_variables_from(invoker, [ "testonly" ])
4357        deps = [ ":$_unpack_target_name" ]
4358        mergeable_android_manifests = [ "${_output_path}/AndroidManifest.xml" ]
4359      }
4360    }
4361
4362    # Create the android_assets target for assets
4363    if (_use_scanned_assets) {
4364      _assets_target_name = "${target_name}__assets"
4365      android_assets(_assets_target_name) {
4366        forward_variables_from(invoker, [ "testonly" ])
4367        renaming_sources = []
4368        renaming_destinations = []
4369        foreach(_asset_file, _scanned_files.assets) {
4370          _original_path =
4371              get_path_info(rebase_path(_asset_file, "", _output_path),
4372                            "abspath")
4373          _updated_path = string_replace(_asset_file, "assets/", "", 1)
4374          renaming_sources += [ _original_path ]
4375          renaming_destinations += [ _updated_path ]
4376        }
4377      }
4378    }
4379
4380    # Create android_java_prebuilt target for classes.jar.
4381    if (_scanned_files.has_classes_jar) {
4382      _java_library_vars = [
4383        "bytecode_rewriter_target",
4384        "enable_bytecode_checks",
4385        "enable_jetify",
4386        "jar_excluded_patterns",
4387        "jar_included_patterns",
4388        "missing_classes_allowlist",
4389        "requires_android",
4390        "testonly",
4391      ]
4392
4393      # Create android_java_prebuilt target for extra jars within jars/.
4394      _subjar_targets = []
4395      foreach(_tuple, _scanned_files.subjar_tuples) {
4396        _current_target = "${target_name}__subjar_${_tuple[0]}"
4397        _subjar_targets += [ ":$_current_target" ]
4398        java_prebuilt(_current_target) {
4399          forward_variables_from(invoker, _java_library_vars)
4400          deps = [ ":$_unpack_target_name" ]
4401          if (!defined(requires_android)) {
4402            requires_android = true
4403          }
4404          supports_android = true
4405          jar_path = "$_output_path/${_tuple[1]}"
4406          _base_output_name = get_path_info(jar_path, "name")
4407          output_name = "${invoker.target_name}-$_base_output_name"
4408          public_target_label = invoker.target_name
4409        }
4410      }
4411
4412      _jar_target_name = "${target_name}__classes"
4413      java_prebuilt(_jar_target_name) {
4414        forward_variables_from(invoker, _java_library_vars)
4415        forward_variables_from(invoker,
4416                               [
4417                                 "deps",
4418                                 "input_jars_paths",
4419                                 "proguard_configs",
4420                               ])
4421        if (!defined(deps)) {
4422          deps = []
4423        }
4424        deps += _subjar_targets + [ ":$_unpack_target_name" ]
4425        if (defined(_res_target_name)) {
4426          deps += [ ":$_res_target_name" ]
4427        }
4428        if (!defined(requires_android)) {
4429          requires_android = true
4430        }
4431        supports_android = true
4432        jar_path = "$_output_path/classes.jar"
4433        aar_path = invoker.aar_path
4434        output_name = invoker.target_name
4435
4436        if (!_ignore_proguard_configs) {
4437          if (!defined(proguard_configs)) {
4438            proguard_configs = []
4439          }
4440          if (_scanned_files.has_proguard_flags) {
4441            proguard_configs += [ "$_output_path/proguard.txt" ]
4442          }
4443        }
4444        public_target_label = invoker.target_name
4445      }
4446    }
4447
4448    java_group(target_name) {
4449      forward_variables_from(invoker,
4450                             [
4451                               "testonly",
4452                               "visibility",
4453                             ])
4454      public_deps = [ ":$_unpack_target_name" ]
4455      deps = []
4456      if (defined(_jar_target_name)) {
4457        deps += [ ":$_jar_target_name" ]
4458
4459        # Although subjars are meant to be private, we add them as deps here
4460        # because in practice they seem to contain classes required to be in the
4461        # classpath.
4462        deps += _subjar_targets
4463      }
4464      if (defined(_res_target_name)) {
4465        deps += [ ":$_res_target_name" ]
4466      }
4467      if (defined(_assets_target_name)) {
4468        deps += [ ":$_assets_target_name" ]
4469      }
4470    }
4471  }
4472
4473  # Create an Android application bundle from one base android_apk target,
4474  # and zero or more associated android_apk.
4475  #
4476  # Variables:
4477  #    base_module_target: Name of the android_app_bundle_module target
4478  #      corresponding to the base module for this application bundle. The
4479  #      bundle file will include the same content in its base module, though in
4480  #      a slightly different format.
4481  #
4482  #    bundle_base_path: Optional. If set, the bundle will be output to this
4483  #      directory. Defaults to "$root_build_dir/apks".
4484  #
4485  #    bundle_name: Optional. If set, the bundle will be output to the
4486  #      filename "${bundle_name}.aab".
4487  #
4488  #    extra_modules: Optional list of scopes, one per extra module used by
4489  #      this bundle. Each scope must have a 'name' field that specifies the
4490  #      module name (which cannot be 'base', since this is reserved for the
4491  #      base module), and an 'apk_target' field that specified the
4492  #      corresponding android_apk target name the module is modeled on.
4493  #
4494  #    enable_language_splits: Optional. If true, enable APK splits based
4495  #      on languages.
4496  #
4497  #    sign_bundle: Optional. If true, sign the bundle. Default is false
4498  #      because signing is very slow, and there is no reason to do it
4499  #      unless one wants to upload the bundle to the Play Store (e.g.
4500  #      for official builds).
4501  #
4502  #    keystore_path: optional keystore path, used only when generating APKs.
4503  #    keystore_name: optional keystore name, used only when generating APKs.
4504  #    keystore_password: optional keystore password, used only when
4505  #      generating APKs.
4506  #
4507  #    command_line_flags_file: Optional. If provided, named of the on-device
4508  #      file that will be used to store command-line arguments. The default
4509  #      is 'command_line_flags_file', but this is typically redefined to
4510  #      something more specific for certain bundles (e.g. the Chromium based
4511  #      APKs use 'chrome-command-line', the WebView one uses
4512  #      'webview-command-line').
4513  #
4514  #    proguard_enabled: Optional. True if proguarding is enabled for this
4515  #      bundle. Default is to enable this only for release builds. Note that
4516  #      this will always perform synchronized proguarding.
4517  #
4518  #    enable_multidex: Optional. Enable multidexing of optimized modules jars
4519  #      when using synchronized proguarding. Only applies to base module.
4520  #
4521  #    proguard_android_sdk_dep: Optional. android_system_java_prebuilt() target
4522  #      used as a library jar for synchronized proguarding.
4523  #
4524  #    compress_shared_libraries: Optional. Whether to compress shared libraries
4525  #      such that they are extracted upon install. Libraries prefixed with
4526  #      "crazy." are never compressed.
4527  #
4528  #    system_image_locale_allowlist: List of locales that should be included
4529  #      on system APKs generated from this bundle.
4530  #
4531  #    static_library_provider: Specifies a single target that this target will
4532  #      use as a static library APK.
4533  #      Additionally, when allotting libraries to be packaged into modules, the
4534  #      libraries packaged into the static library will be accounted for to
4535  #      avoid library duplication. Effectively, the static library will be
4536  #      treated as the parent of the base module.
4537  #
4538  #    expected_libs_and_assets: Verify the list of included native libraries
4539  #      and assets is consistent with the given expectation file.
4540  #    expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff
4541  #      with this file as the base.
4542  #    expected_proguard_config: Checks that the merged set of proguard flags
4543  #      matches the given config.
4544  #    expected_proguard_config_base: Treat expected_proguard_config as a diff
4545  #      with this file as the base.
4546  #
4547  #    version_code: Optional. Version code of the target.
4548  #
4549  #    is_multi_abi: If true will add a library placeholder for the missing ABI
4550  #      if either the primary or the secondary ABI has no native libraries set.
4551  #
4552  #    default_modules_for_testing: (optional): A list of DFM that the wrapper
4553  #      script should install. This is for local testing only, and does not
4554  #      affect the actual DFM in production.
4555  # Example:
4556  #   android_app_bundle("chrome_public_bundle") {
4557  #      base_module_target = "//chrome/android:chrome_public_apk"
4558  #      extra_modules = [
4559  #        { # NOTE: Scopes require one field per line, and no comma separators.
4560  #          name = "my_module"
4561  #          module_target = ":my_module"
4562  #        },
4563  #      ]
4564  #   }
4565  #
4566  template("android_app_bundle") {
4567    _target_name = target_name
4568    _uses_static_library = defined(invoker.static_library_provider)
4569    _proguard_enabled =
4570        defined(invoker.proguard_enabled) && invoker.proguard_enabled
4571
4572    if (defined(invoker.version_code)) {
4573      _version_code = invoker.version_code
4574    } else {
4575      _version_code = android_default_version_code
4576    }
4577
4578    if (android_override_version_code != "") {
4579      _version_code = android_override_version_code
4580    }
4581
4582    # Prevent "unused variable".
4583    not_needed([ "_version_code" ])
4584
4585    _bundle_base_path = "$root_build_dir/apks"
4586    if (defined(invoker.bundle_base_path)) {
4587      _bundle_base_path = invoker.bundle_base_path
4588    }
4589
4590    _bundle_name = _target_name
4591    if (defined(invoker.bundle_name)) {
4592      _bundle_name = invoker.bundle_name
4593    }
4594    _bundle_path = "$_bundle_base_path/${_bundle_name}.aab"
4595    _rebased_bundle_path = rebase_path(_bundle_path, root_build_dir)
4596
4597    _base_target_name = get_label_info(invoker.base_module_target, "name")
4598    _base_target_gen_dir =
4599        get_label_info(invoker.base_module_target, "target_gen_dir")
4600    _base_module_build_config =
4601        "$_base_target_gen_dir/${_base_target_name}.build_config"
4602    _base_module_build_config_target =
4603        "${invoker.base_module_target}$build_config_target_suffix"
4604    _rebased_base_module_build_config =
4605        rebase_path(_base_module_build_config, root_build_dir)
4606
4607    _modules = [
4608      {
4609        name = "base"
4610        module_target = invoker.base_module_target
4611        build_config = _base_module_build_config
4612        build_config_target = _base_module_build_config_target
4613        if (_uses_static_library) {
4614          parent = "lib"
4615        }
4616      },
4617    ]
4618
4619    _enable_multidex =
4620        !defined(invoker.enable_multidex) || invoker.enable_multidex
4621
4622    if (!_proguard_enabled && defined(invoker.min_sdk_version)) {
4623      not_needed(invoker, [ "min_sdk_version" ])
4624    }
4625
4626    # Prevent "unused variable".
4627    not_needed([ "_enable_multidex" ])
4628
4629    if (_proguard_enabled) {
4630      _uses_static_library_synchronized_proguard =
4631          defined(invoker.static_library_synchronized_proguard) &&
4632          invoker.static_library_synchronized_proguard
4633
4634      # TODO(crbug.com/1032609): Remove dexsplitter from Trichrome Proguard.
4635      _dex_target = "${_target_name}__dex"
4636      _proguard_mapping_path = "${_bundle_path}.mapping"
4637    }
4638
4639    assert(_proguard_enabled || !defined(invoker.enable_multidex),
4640           "Bundle only adds dexing step if proguarding is enabled.")
4641
4642    if (defined(invoker.extra_modules)) {
4643      _module_count = 0
4644      not_needed([ "_module_count" ])
4645
4646      foreach(_module, invoker.extra_modules) {
4647        _module_count += 1
4648        assert(defined(_module.name),
4649               "Missing 'name' field for extra module #${_module_count}.")
4650        assert(_module.name != "base",
4651               "Module name 'base' is reserved for the main bundle module")
4652        assert(
4653            defined(_module.module_target),
4654            "Missing 'module_target' field for extra module ${_module.name}.")
4655        _module_target = _module.module_target
4656        _module_target_name = get_label_info(_module_target, "name")
4657        _module_target_gen_dir =
4658            get_label_info(_module_target, "target_gen_dir")
4659        _module.build_config =
4660            "$_module_target_gen_dir/${_module_target_name}.build_config"
4661        _module.build_config_target =
4662            "$_module_target$build_config_target_suffix"
4663        _module.parent = "base"
4664        _modules += [ _module ]
4665      }
4666    }
4667
4668    # Make build config, which is required for synchronized proguarding.
4669    _module_java_targets = []
4670    _module_build_configs = []
4671    _module_targets = []
4672    foreach(_module, _modules) {
4673      _module_targets += [ _module.module_target ]
4674      _module_java_targets += [ "${_module.module_target}__java" ]
4675      _module_build_configs += [ _module.build_config ]
4676    }
4677
4678    if (_uses_static_library) {
4679      _lib_proxy_module = {
4680        name = "lib"
4681      }
4682      _static_library_target_name =
4683          get_label_info(invoker.static_library_provider, "name")
4684      _static_library_gen_dir =
4685          get_label_info(invoker.static_library_provider, "target_gen_dir")
4686      _lib_proxy_module.build_config =
4687          "$_static_library_gen_dir/$_static_library_target_name.build_config"
4688      _lib_proxy_module.build_config_target =
4689          "${invoker.static_library_provider}$build_config_target_suffix"
4690    }
4691
4692    # Allot native libraries to modules they should be packaged into. This is
4693    # necessary since all libraries that are depended on by multiple modules
4694    # have to go into base or the static shared library if it exists.
4695    # TODO(crbug.com/1021565): It would be nice if this lived outside the
4696    # android_app_bundle template and the static shared library would pull in
4697    # the libs as allotted by this step.
4698    _native_libraries_config =
4699        "$target_gen_dir/$_target_name.native_libraries_config"
4700    _native_libraries_config_target = "${_target_name}__allot_native_libraries"
4701    allot_native_libraries(_native_libraries_config_target) {
4702      modules = _modules
4703      native_libraries_filearg_keys = [
4704        "native:libraries",
4705        "native:loadable_modules",
4706      ]
4707      output = _native_libraries_config
4708      if (_uses_static_library) {
4709        modules += [ _lib_proxy_module ]
4710      }
4711    }
4712    if (defined(android_app_secondary_abi)) {
4713      _secondary_abi_native_libraries_config =
4714          "$target_gen_dir/$_target_name.secondary_abi_native_libraries_config"
4715      _secondary_abi_native_libraries_config_target =
4716          "${_target_name}__allot_secondary_abi_native_libraries"
4717      allot_native_libraries(_secondary_abi_native_libraries_config_target) {
4718        modules = _modules
4719        native_libraries_filearg_keys = [
4720          "native:secondary_abi_libraries",
4721          "native:secondary_abi_loadable_modules",
4722        ]
4723        output = _secondary_abi_native_libraries_config
4724        if (_uses_static_library) {
4725          modules += [ _lib_proxy_module ]
4726        }
4727      }
4728    }
4729
4730    # Used to expose the module Java targets of the bundle.
4731    group("${_target_name}__java") {
4732      deps = _module_java_targets
4733    }
4734    group("${_target_name}__compile_resources") {
4735      deps = [ "${invoker.base_module_target}__compile_resources" ]
4736    }
4737
4738    _build_config = "$target_gen_dir/${_target_name}.build_config"
4739    _rebased_build_config = rebase_path(_build_config, root_build_dir)
4740    _build_config_target = "$_target_name$build_config_target_suffix"
4741    if (defined(invoker.proguard_android_sdk_dep)) {
4742      proguard_android_sdk_dep_ = invoker.proguard_android_sdk_dep
4743    } else {
4744      proguard_android_sdk_dep_ = "//third_party/android_sdk:android_sdk_java"
4745    }
4746
4747    if (_proguard_enabled) {
4748      _proguard_mapping_path = "${_bundle_path}.mapping"
4749    }
4750
4751    write_build_config(_build_config_target) {
4752      type = "android_app_bundle"
4753      possible_config_deps = _module_targets + [ proguard_android_sdk_dep_ ]
4754      build_config = _build_config
4755      proguard_enabled = _proguard_enabled
4756      module_build_configs = _module_build_configs
4757
4758      if (_proguard_enabled) {
4759        proguard_mapping_path = _proguard_mapping_path
4760      }
4761    }
4762
4763    if (_proguard_enabled) {
4764      # If this Bundle uses a static library, the static library APK will
4765      # create the synchronized dex file path.
4766      if (_uses_static_library_synchronized_proguard) {
4767        if (defined(invoker.min_sdk_version)) {
4768          not_needed(invoker, [ "min_sdk_version" ])
4769        }
4770      } else {
4771        dex(_dex_target) {
4772          forward_variables_from(invoker,
4773                                 [
4774                                   "expected_proguard_config",
4775                                   "expected_proguard_config_base",
4776                                   "min_sdk_version",
4777                                 ])
4778          if (defined(expected_proguard_config)) {
4779            top_target_name = _target_name
4780          }
4781          enable_multidex = _enable_multidex
4782          proguard_enabled = true
4783          proguard_mapping_path = _proguard_mapping_path
4784          proguard_sourcefile_suffix = "$android_channel-$_version_code"
4785          build_config = _build_config
4786
4787          deps = _module_java_targets + [ ":$_build_config_target" ]
4788          modules = _modules
4789        }
4790      }
4791    }
4792
4793    _all_create_module_targets = []
4794    _all_module_zip_paths = []
4795    _all_module_build_configs = []
4796    foreach(_module, _modules) {
4797      _module_target = _module.module_target
4798      _module_build_config = _module.build_config
4799      _module_build_config_target = _module.build_config_target
4800
4801      if (!_proguard_enabled) {
4802        _dex_target_for_module = "${_module_target}__final_dex"
4803      } else {
4804        _dex_target_for_module = ":$_dex_target"
4805      }
4806
4807      # Generate one module .zip file per bundle module.
4808      #
4809      # Important: the bundle tool uses the module's zip filename as
4810      # the internal module name inside the final bundle, in other words,
4811      # this file *must* be named ${_module.name}.zip
4812      _create_module_target = "${_target_name}__${_module.name}__create"
4813      _module_zip_path = "$target_gen_dir/$target_name/${_module.name}.zip"
4814
4815      create_android_app_bundle_module(_create_module_target) {
4816        forward_variables_from(invoker,
4817                               [
4818                                 "is_multi_abi",
4819                                 "min_sdk_version",
4820                                 "uncompress_dex",
4821                                 "proguard_enabled",
4822                               ])
4823        module_name = _module.name
4824        build_config = _module_build_config
4825        module_zip_path = _module_zip_path
4826        native_libraries_config = _native_libraries_config
4827
4828        if (module_name == "base" &&
4829            defined(invoker.expected_libs_and_assets)) {
4830          forward_variables_from(invoker,
4831                                 [
4832                                   "expected_libs_and_assets",
4833                                   "expected_libs_and_assets_base",
4834                                 ])
4835          top_target_name = _target_name
4836          build_config_target = _module_build_config_target
4837          native_libraries_config_target = ":$_native_libraries_config_target"
4838          if (defined(android_app_secondary_abi)) {
4839            secondary_abi_native_libraries_config_target =
4840                ":$_secondary_abi_native_libraries_config_target"
4841          }
4842        }
4843
4844        deps = [
4845          ":$_native_libraries_config_target",
4846          _dex_target_for_module,
4847          _module_build_config_target,
4848          _module_target,
4849        ]
4850
4851        if (defined(android_app_secondary_abi)) {
4852          secondary_abi_native_libraries_config =
4853              _secondary_abi_native_libraries_config
4854          deps += [ ":$_secondary_abi_native_libraries_config_target" ]
4855        }
4856      }
4857
4858      _all_create_module_targets += [
4859        ":$_create_module_target",
4860        _module_build_config_target,
4861        "${_module_target}__compile_resources",
4862      ]
4863      _all_module_zip_paths += [ _module_zip_path ]
4864      _all_module_build_configs += [ _module_build_config ]
4865    }
4866
4867    _all_rebased_module_zip_paths =
4868        rebase_path(_all_module_zip_paths, root_build_dir)
4869
4870    _sign_bundle = defined(invoker.sign_bundle) && invoker.sign_bundle
4871
4872    _enable_language_splits = defined(invoker.enable_language_splits) &&
4873                              invoker.enable_language_splits
4874
4875    _split_dimensions = []
4876    if (_enable_language_splits) {
4877      _split_dimensions += [ "language" ]
4878    }
4879
4880    _keystore_path = android_keystore_path
4881    _keystore_password = android_keystore_password
4882    _keystore_name = android_keystore_name
4883
4884    if (defined(invoker.keystore_path)) {
4885      _keystore_path = invoker.keystore_path
4886      _keystore_password = invoker.keystore_password
4887      _keystore_name = invoker.keystore_name
4888    }
4889
4890    _rebased_keystore_path = rebase_path(_keystore_path, root_build_dir)
4891
4892    if (_sign_bundle) {
4893      # For now, the same keys are used to sign the bundle and the set of
4894      # generated APKs. In the future, signing the bundle may require a
4895      # different set of keys.
4896      _bundle_keystore_name = _keystore_name
4897    }
4898
4899    _bundle_target_name = "${_target_name}__bundle"
4900    action_with_pydeps(_bundle_target_name) {
4901      # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
4902      run_under_python2 = true
4903
4904      script = "//build/android/gyp/create_app_bundle.py"
4905      inputs = _all_module_zip_paths + _all_module_build_configs
4906      outputs = [ _bundle_path ]
4907      deps = _all_create_module_targets + [ ":$_build_config_target" ]
4908      args = [
4909        "--out-bundle=$_rebased_bundle_path",
4910        "--rtxt-out-path=$_rebased_bundle_path.R.txt",
4911        "--pathmap-out-path=$_rebased_bundle_path.pathmap.txt",
4912        "--module-zips=$_all_rebased_module_zip_paths",
4913      ]
4914      if (_sign_bundle) {
4915        args += [
4916          "--keystore-path",
4917          _rebased_keystore_path,
4918          "--keystore-password",
4919          _keystore_password,
4920          "--key-name",
4921          _bundle_keystore_name,
4922        ]
4923      }
4924      if (_split_dimensions != []) {
4925        args += [ "--split-dimensions=$_split_dimensions" ]
4926      }
4927      if (defined(invoker.compress_shared_libraries) &&
4928          invoker.compress_shared_libraries) {
4929        args += [ "--compress-shared-libraries" ]
4930      }
4931      if (treat_warnings_as_errors) {
4932        args += [ "--warnings-as-errors" ]
4933      }
4934
4935      if (_enable_language_splits) {
4936        args += [
4937          "--base-allowlist-rtxt-path=@FileArg(" + "${_rebased_base_module_build_config}:deps_info:base_allowlist_rtxt_path)",
4938          "--base-module-rtxt-path=@FileArg(" +
4939              "${_rebased_base_module_build_config}:deps_info:r_text_path)",
4940        ]
4941      }
4942      if (defined(invoker.validate_services) && invoker.validate_services) {
4943        args += [ "--validate-services" ]
4944      }
4945
4946      foreach(_module, _modules) {
4947        _rebased_build_config =
4948            rebase_path(_module.build_config, root_build_dir)
4949        args += [
4950          "--uncompressed-assets=@FileArg(" +
4951              "$_rebased_build_config:uncompressed_assets)",
4952          "--rtxt-in-paths=@FileArg(" +
4953              "$_rebased_build_config:deps_info:r_text_path)",
4954          "--pathmap-in-paths=@FileArg(" +
4955              "$_rebased_build_config:deps_info:module_pathmap_path)",
4956          "--module-name=" + _module.name,
4957        ]
4958      }
4959
4960      # http://crbug.com/725224. Fix for bots running out of memory.
4961      if (defined(java_cmd_pool_size)) {
4962        pool = "//build/config/android:java_cmd_pool($default_toolchain)"
4963      } else {
4964        pool = "//build/toolchain:link_pool($default_toolchain)"
4965      }
4966    }
4967
4968    # Create size info files for targets that care about size
4969    # (have proguard enabled).
4970    if (_proguard_enabled) {
4971      # Merge all module targets to obtain size info files for all targets.
4972      _all_module_targets = _module_targets
4973
4974      _size_info_target = "${_target_name}__size_info"
4975      create_size_info_files(_size_info_target) {
4976        name = "$_bundle_name.aab"
4977        deps = _all_module_targets + [ ":$_build_config_target" ]
4978        module_build_configs = _all_module_build_configs
4979      }
4980    }
4981
4982    if (_uses_static_library) {
4983      _install_artifacts_target = "${target_name}__install_artifacts"
4984      _install_artifacts_json =
4985          "${target_gen_dir}/${target_name}.install_artifacts"
4986      generated_file(_install_artifacts_target) {
4987        output_conversion = "json"
4988        deps = [ invoker.static_library_provider ]
4989        outputs = [ _install_artifacts_json ]
4990        data_keys = [ "install_artifacts" ]
4991        rebase = root_build_dir
4992      }
4993    }
4994
4995    # Generate a wrapper script for the bundle.
4996    _android_aapt2_path = android_sdk_tools_bundle_aapt2
4997
4998    _bundle_apks_path = "$_bundle_base_path/$_bundle_name.apks"
4999    _bundle_wrapper_script_dir = "$root_build_dir/bin"
5000    _bundle_wrapper_script_path = "$_bundle_wrapper_script_dir/$_target_name"
5001
5002    action_with_pydeps("${_target_name}__wrapper_script") {
5003      # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
5004      run_under_python2 = true
5005
5006      script = "//build/android/gyp/create_bundle_wrapper_script.py"
5007      inputs = [ _base_module_build_config ]
5008      outputs = [ _bundle_wrapper_script_path ]
5009
5010      # Telemetry for bundles uses the wrapper script for installation.
5011      data = [
5012        _bundle_wrapper_script_path,
5013        _android_aapt2_path,
5014        _keystore_path,
5015        _bundle_path,
5016      ]
5017      data_deps = [
5018        "//build/android:bundle_wrapper_script_py",
5019        "//tools/android/md5sum",
5020      ]
5021
5022      deps = [ _base_module_build_config_target ]
5023      args = [
5024        "--script-output-path",
5025        rebase_path(_bundle_wrapper_script_path, root_build_dir),
5026        "--package-name=@FileArg(" +
5027            "$_rebased_base_module_build_config:deps_info:package_name)",
5028        "--aapt2",
5029        rebase_path(_android_aapt2_path, root_build_dir),
5030        "--bundle-path",
5031        _rebased_bundle_path,
5032        "--bundle-apks-path",
5033        rebase_path(_bundle_apks_path, root_build_dir),
5034        "--target-cpu=$target_cpu",
5035        "--keystore-path",
5036        _rebased_keystore_path,
5037        "--keystore-password",
5038        _keystore_password,
5039        "--key-name",
5040        _keystore_name,
5041      ]
5042      if (defined(invoker.default_modules_for_testing)) {
5043        args += [ "--default-modules" ] + invoker.default_modules_for_testing
5044      }
5045      if (defined(invoker.system_image_locale_allowlist)) {
5046        args += [
5047          "--system-image-locales=${invoker.system_image_locale_allowlist}",
5048        ]
5049      }
5050      if (defined(invoker.command_line_flags_file)) {
5051        args += [
5052          "--command-line-flags-file",
5053          invoker.command_line_flags_file,
5054        ]
5055      }
5056      if (_uses_static_library) {
5057        deps += [ ":$_install_artifacts_target" ]
5058        _rebased_install_artifacts_json =
5059            rebase_path(_install_artifacts_json, root_build_dir)
5060        _static_library_apk_path =
5061            "@FileArg($_rebased_install_artifacts_json[])"
5062        args += [
5063          "--additional-apk",
5064          _static_library_apk_path,
5065        ]
5066      }
5067
5068      if (_proguard_enabled) {
5069        args += [
5070          "--proguard-mapping-path",
5071          rebase_path(_proguard_mapping_path, root_build_dir),
5072        ]
5073
5074        # Required by logcat command.
5075        data_deps += [ "//build/android/stacktrace:java_deobfuscate" ]
5076        data += [ _proguard_mapping_path ]
5077      }
5078    }
5079
5080    _enable_lint = defined(invoker.enable_lint) && invoker.enable_lint &&
5081                   !disable_android_lint
5082    if (_enable_lint) {
5083      android_lint("${target_name}__lint") {
5084        forward_variables_from(invoker,
5085                               [
5086                                 "lint_baseline_file",
5087                                 "lint_suppressions_file",
5088                                 "min_sdk_version",
5089                               ])
5090        build_config = _build_config
5091        build_config_dep = ":$_build_config_target"
5092        deps = _module_java_targets
5093        if (defined(invoker.lint_suppressions_dep)) {
5094          deps += [ invoker.lint_suppressions_dep ]
5095        }
5096        if (defined(invoker.lint_min_sdk_version)) {
5097          min_sdk_version = invoker.lint_min_sdk_version
5098        }
5099      }
5100    } else {
5101      not_needed(invoker,
5102                 [
5103                   "lint_baseline_file",
5104                   "lint_min_sdk_version",
5105                   "lint_suppressions_dep",
5106                   "lint_suppressions_file",
5107                 ])
5108    }
5109
5110    group(_target_name) {
5111      public_deps = [
5112        ":$_bundle_target_name",
5113        ":${_target_name}__wrapper_script",
5114      ]
5115      if (defined(_size_info_target)) {
5116        public_deps += [ ":$_size_info_target" ]
5117      }
5118      if (_enable_lint) {
5119        if (!defined(data_deps)) {
5120          data_deps = []
5121        }
5122        data_deps += [ ":${target_name}__lint" ]
5123      }
5124    }
5125
5126    _apks_path = "$root_build_dir/apks/$_bundle_name.apks"
5127    action_with_pydeps("${_target_name}_apks") {
5128      script = "//build/android/gyp/create_app_bundle_apks.py"
5129      inputs = [ _bundle_path ]
5130      outputs = [ _apks_path ]
5131      data = [ _apks_path ]
5132      args = [
5133        "--bundle",
5134        _rebased_bundle_path,
5135        "--output",
5136        rebase_path(_apks_path, root_build_dir),
5137        "--aapt2-path",
5138        rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
5139        "--keystore-path",
5140        rebase_path(android_keystore_path, root_build_dir),
5141        "--keystore-name",
5142        android_keystore_name,
5143        "--keystore-password",
5144        android_keystore_password,
5145      ]
5146      deps = [ ":$_bundle_target_name" ]
5147      metadata = {
5148        install_artifacts = [ _apks_path ]
5149      }
5150      if (defined(invoker.static_library_provider)) {
5151        metadata.install_artifacts_barrier = []
5152      }
5153
5154      # http://crbug.com/725224. Fix for bots running out of memory.
5155      if (defined(java_cmd_pool_size)) {
5156        pool = "//build/config/android:java_cmd_pool($default_toolchain)"
5157      } else {
5158        pool = "//build/toolchain:link_pool($default_toolchain)"
5159      }
5160    }
5161  }
5162
5163  # Create an .apks file from an .aab file. The .apks file will contain the
5164  # minimal set of .apk files needed for tracking binary size.
5165  # The file will be created at "$bundle_path_without_extension.minimal.apks".
5166  #
5167  # Variables:
5168  #   bundle_path: Path to the input .aab file.
5169  #
5170  # Example:
5171  #   create_app_bundle_minimal_apks("minimal_apks") {
5172  #     deps = [
5173  #       ":bundle_target",
5174  #     ]
5175  #     bundle_path = "$root_build_dir/apks/Bundle.aab"
5176  #   }
5177  template("create_app_bundle_minimal_apks") {
5178    action_with_pydeps(target_name) {
5179      forward_variables_from(invoker,
5180                             [
5181                               "deps",
5182                               "testonly",
5183                             ])
5184      script = "//build/android/gyp/create_app_bundle_apks.py"
5185      _dir = get_path_info(invoker.bundle_path, "dir")
5186      _name = get_path_info(invoker.bundle_path, "name")
5187      _output_path = "$_dir/$_name.minimal.apks"
5188      outputs = [ _output_path ]
5189      inputs = [ invoker.bundle_path ]
5190      args = [
5191        "--bundle",
5192        rebase_path(invoker.bundle_path, root_build_dir),
5193        "--output",
5194        rebase_path(_output_path, root_build_dir),
5195        "--aapt2-path",
5196        rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
5197        "--keystore-path",
5198        rebase_path(android_keystore_path, root_build_dir),
5199        "--keystore-name",
5200        android_keystore_name,
5201        "--keystore-password",
5202        android_keystore_password,
5203        "--minimal",
5204      ]
5205    }
5206  }
5207}
5208
5209# Generate an Android resources target that contains localized strings
5210# describing the current locale used by the Android framework to display
5211# UI strings. These are used by
5212# org.chromium.chrome.browser.ChromeLocalizationUtils.
5213#
5214# Variables:
5215#    ui_locales: List of Chromium locale names to generate resources for.
5216#
5217template("generate_ui_locale_resources") {
5218  _generating_target_name = "${target_name}__generate"
5219  _rebased_output_zip_path = rebase_path(target_gen_dir, root_gen_dir)
5220  _output_zip = "${root_out_dir}/resource_zips/${_rebased_output_zip_path}/" +
5221                "${target_name}.zip"
5222
5223  action_with_pydeps(_generating_target_name) {
5224    script = "//build/android/gyp/create_ui_locale_resources.py"
5225    outputs = [ _output_zip ]
5226    args = [
5227      "--locale-list=${invoker.ui_locales}",
5228      "--output-zip",
5229      rebase_path(_output_zip, root_build_dir),
5230    ]
5231  }
5232
5233  android_generated_resources(target_name) {
5234    generating_target_name = ":$_generating_target_name"
5235    generated_resources_zip = _output_zip
5236  }
5237}
5238