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