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