xref: /aosp_15_r20/external/angle/build/config/android/rules.gni (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1# Copyright 2014 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/android/abi.gni")
6import("//build/config/android/copy_ex.gni")
7import("//build/config/chrome_build.gni")
8import("//build/config/clang/clang.gni")
9import("//build/config/rts.gni")
10import("//build/config/sanitizers/sanitizers.gni")
11import("//build_overrides/build.gni")
12
13assert(
14    is_android || is_robolectric,
15    "current_toolchain=$current_toolchain default_toolchain=$default_toolchain")
16
17_sanitizer_runtimes = []
18if (use_cfi_diag || is_ubsan_any) {
19  _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.ubsan_standalone-$sanitizer_arch-android.so" ]
20}
21if (is_asan) {
22  _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.asan-$sanitizer_arch-android.so" ]
23}
24
25# Creates a dist directory for a native executable.
26#
27# Running a native executable on a device requires all the shared library
28# dependencies of that executable. To make it easier to install and run such an
29# executable, this will create a directory containing the native exe and all
30# it's library dependencies.
31#
32# Note: It's usually better to package things as an APK than as a native
33# executable.
34#
35# Variables
36#   dist_dir: Directory for the exe and libraries. Everything in this directory
37#     will be deleted before copying in the exe and libraries.
38#   binary: Path to (stripped) executable.
39#   extra_files: List of extra files to copy in (optional).
40#
41# Example
42#   create_native_executable_dist("foo_dist") {
43#     dist_dir = "$root_build_dir/foo_dist"
44#     binary = "$root_build_dir/foo"
45#     deps = [ ":the_thing_that_makes_foo" ]
46#   }
47template("create_native_executable_dist") {
48  forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
49
50  _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list"
51
52  _sanitizer_runtimes_target_name = "${target_name}__sanitizer_runtimes"
53  group(_sanitizer_runtimes_target_name) {
54    metadata = {
55      shared_libraries = _sanitizer_runtimes
56    }
57  }
58
59  generated_file("${target_name}__library_list") {
60    forward_variables_from(invoker, [ "deps" ])
61    if (!defined(deps)) {
62      deps = []
63    }
64    deps += [ ":${_sanitizer_runtimes_target_name}" ]
65    output_conversion = "json"
66    outputs = [ _libraries_list ]
67    data_keys = [ "shared_libraries" ]
68    walk_keys = [ "shared_libraries_barrier" ]
69    rebase = root_build_dir
70  }
71
72  copy_ex(target_name) {
73    inputs = [
74      _libraries_list,
75      invoker.binary,
76    ]
77
78    dest = invoker.dist_dir
79    data = [ "${invoker.dist_dir}/" ]
80
81    _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir)
82    _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir)
83    args = [
84      "--clear",
85      "--files=@FileArg($_rebased_libraries_list)",
86      "--files=$_rebased_binaries_list",
87    ]
88    if (defined(invoker.extra_files)) {
89      _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir)
90      args += [ "--files=$_rebased_extra_files" ]
91    }
92
93    _depfile = "$target_gen_dir/$target_name.d"
94    _stamp_file = "$target_gen_dir/$target_name.stamp"
95    outputs = [ _stamp_file ]
96    args += [
97      "--depfile",
98      rebase_path(_depfile, root_build_dir),
99      "--stamp",
100      rebase_path(_stamp_file, root_build_dir),
101    ]
102
103    deps = [ ":${target_name}__library_list" ]
104    if (defined(invoker.deps)) {
105      deps += invoker.deps
106    }
107  }
108}
109
110if (!is_robolectric && enable_java_templates) {
111  import("//build/config/android/config.gni")
112  import("//build/config/android/internal_rules.gni")
113  import("//build/config/compiler/compiler.gni")
114  import("//build/config/coverage/coverage.gni")
115  import("//build/config/profiling/profiling.gni")
116  import("//build/config/python.gni")
117  import("//build/config/zip.gni")
118  import("//build/toolchain/toolchain.gni")
119
120  _BUNDLETOOL_JAR_PATH =
121      "//third_party/android_build_tools/bundletool/cipd/bundletool.jar"
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" ])
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 = default_target_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 = default_target_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          java_targets = [ ":$_java_binary_target_name" ]
1234          add_stubs_for_missing_jni = true
1235        }
1236        _jni_srcjar_deps = [ ":$_jni_srcjar_target_name" ]
1237      }
1238      _native_libraries_target_name = "${target_name}__native_libraries"
1239      write_native_libraries_java(_native_libraries_target_name) {
1240        enable_chromium_linker = false
1241        use_final_fields = true
1242        if (defined(_shared_library_list_file)) {
1243          native_libraries_list_file = _shared_library_list_file
1244        }
1245      }
1246    }
1247
1248    java_library_impl(_java_binary_target_name) {
1249      forward_variables_from(invoker,
1250                             "*",
1251                             TESTONLY_AND_VISIBILITY + [
1252                                   "deps",
1253                                   "extra_args",
1254                                   "shared_libraries",
1255                                 ])
1256      type = "robolectric_binary"
1257      main_target_name = invoker.target_name
1258
1259      deps = _invoker_deps
1260      testonly = true
1261      main_class = _main_class
1262      wrapper_script_name = "helper/$main_target_name"
1263
1264      # As of April 2021, adding -XX:TieredStopAtLevel=1 does not affect the
1265      # wall time of a single robolectric shard, but does reduce the CPU time by
1266      # 66%, which makes sharding more effective.
1267      tiered_stop_at_level_one = true
1268
1269      is_robolectric = true
1270      include_android_sdk = true
1271      alternative_android_sdk_dep =
1272          "//third_party/robolectric:robolectric_test_sdk_java"
1273
1274      if (!defined(srcjar_deps)) {
1275        srcjar_deps = []
1276      }
1277      srcjar_deps += [
1278        ":$_compile_resources_target_name",
1279        "//build/android:build_config_for_robolectric_srcjar",
1280      ]
1281      if (_generate_final_jni) {
1282        srcjar_deps += [ ":$_native_libraries_target_name" ] + _jni_srcjar_deps
1283      }
1284    }
1285
1286    test_runner_script(target_name) {
1287      forward_variables_from(invoker,
1288                             [
1289                               "assert_no_deps",
1290                               "extra_args",
1291                               "visibility",
1292                             ])
1293      test_name = invoker.target_name
1294      test_suite = invoker.target_name
1295      test_type = "junit"
1296      ignore_all_data_deps = true
1297      resource_apk = _apkbuilder_output
1298      deps = [
1299        ":$_apkbuilder_target_name",
1300        ":$_build_config_target_name",
1301        ":${_java_binary_target_name}__host",
1302        ":${_java_binary_target_name}__java_binary_script",
1303        ":${_java_binary_target_name}__validate",
1304        "//third_party/robolectric:robolectric_runtime_jars",
1305      ]
1306      if (defined(invoker.shared_libraries)) {
1307        data_deps = invoker.shared_libraries
1308      }
1309
1310      # Add non-libary deps, since the __host target does not depend on them.
1311      deps += filter_exclude(_invoker_deps, java_library_patterns)
1312
1313      metadata = {
1314        # Allows metadata collection via apk targets that traverse only java deps.
1315        java_walk_keys = [ ":${_java_binary_target_name}__host" ]
1316      }
1317    }
1318  }
1319
1320  # Declare a java library target
1321  #
1322  # Variables
1323  #   deps: Specifies the dependencies of this target. Java targets in this list
1324  #     will be added to the javac classpath.
1325  #   public_deps: Dependencies that this target exposes as part of its public API.
1326  #     public_deps do not need to be listed in both the 'deps' and 'public_deps' lists.
1327  #   annotation_processor_deps: List of java_annotation_processor targets to
1328  #     use when compiling.
1329  #
1330  #   jar_path: Path to a prebuilt jar. Mutually exclusive with sources &
1331  #     srcjar_deps.
1332  #   sources: List of .java files included in this library.
1333  #   srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
1334  #     will be added to sources and be included in this library.
1335  #
1336  #   input_jars_paths: A list of paths to the jars that should be included
1337  #     in the compile-time classpath. These are in addition to library .jars
1338  #     that appear in deps.
1339  #
1340  #   chromium_code: If true, extra analysis warning/errors will be enabled.
1341  #   enable_errorprone: If true, enables the errorprone compiler.
1342  #   enable_nullaway: Requires enable_errorprone. Enables NullAway plugin.
1343  #   skip_build_server: If true, avoids sending tasks to the build server.
1344  #
1345  #   jar_excluded_patterns: List of patterns of .class files to exclude.
1346  #   jar_included_patterns: List of patterns of .class files to include.
1347  #     When omitted, all classes not matched by jar_excluded_patterns are
1348  #     included. When specified, all non-matching .class files are stripped.
1349  #
1350  #   low_classpath_priority: Indicates that the library should be placed at the
1351  #     end of the classpath. The default classpath order has libraries ordered
1352  #     before the libraries that they depend on. 'low_classpath_priority' is
1353  #     useful when one java_library() overrides another via
1354  #     'jar_excluded_patterns' and the overriding library does not depend on
1355  #     the overridee.
1356  #
1357  #   output_name: File name for the output .jar (not including extension).
1358  #     Defaults to the input .jar file name.
1359  #
1360  #   proguard_configs: List of proguard configs to use in final apk step for
1361  #     any apk that depends on this library.
1362  #
1363  #   supports_android: If true, Android targets (android_library, android_apk)
1364  #     may depend on this target. Note: if true, this target must only use the
1365  #     subset of Java available on Android.
1366  #   bypass_platform_checks: Disables checks about cross-platform (Java/Android)
1367  #     dependencies for this target. This will allow depending on an
1368  #     android_library target, for example.
1369  #   enable_desugar: If false, disables desugaring of lambdas, etc. Use this
1370  #     only when you are sure the library does not require desugaring. E.g.
1371  #     to hide warnings shown from desugaring.
1372  #
1373  #   additional_jar_files: Use to package additional files (Java resources)
1374  #     into the output jar. Pass a list of length-2 lists with format:
1375  #         [ [ path_to_file, path_to_put_in_jar ] ]
1376  #
1377  #   javac_args: Additional arguments to pass to javac.
1378  #   errorprone_args: Additional arguments to pass to errorprone.
1379  #
1380  #   data_deps, testonly
1381  #
1382  # Example
1383  #   java_library("foo_java") {
1384  #     sources = [
1385  #       "org/chromium/foo/Foo.java",
1386  #       "org/chromium/foo/FooInterface.java",
1387  #       "org/chromium/foo/FooService.java",
1388  #     ]
1389  #     deps = [
1390  #       ":bar_java"
1391  #     ]
1392  #     srcjar_deps = [
1393  #       ":foo_generated_enum"
1394  #     ]
1395  #     jar_excluded_patterns = [
1396  #       "*/FooService.class", "org/chromium/FooService\$*.class"
1397  #     ]
1398  #   }
1399  template("java_library") {
1400    java_library_impl(target_name) {
1401      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
1402      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1403      type = "java_library"
1404    }
1405  }
1406
1407  # Declare a java library target for a prebuilt jar
1408  #
1409  # Supports all variables of java_library().
1410  #
1411  # Example
1412  #   java_prebuilt("foo_java") {
1413  #     jar_path = "foo.jar"
1414  #     deps = [
1415  #       ":foo_resources",
1416  #       ":bar_java"
1417  #     ]
1418  #   }
1419  template("java_prebuilt") {
1420    java_library_impl(target_name) {
1421      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
1422      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1423      type = "java_library"
1424    }
1425  }
1426
1427  # Combines all dependent .jar files into a single .jar file.
1428  #
1429  # Variables:
1430  #   output: Path to the output jar.
1431  #   use_interface_jars: Use all dependent interface .jars rather than
1432  #     implementation .jars.
1433  #   use_unprocessed_jars: Use unprocessed / undesugared .jars.
1434  #   direct_deps_only: Do not recurse on deps.
1435  #   jar_excluded_patterns (optional)
1436  #     List of globs for paths to exclude.
1437  #   renaming_rules: rename java classes inside according to these rules.
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/40114668): 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    _supports_android =
1457        !defined(invoker.supports_android) || invoker.supports_android
1458    _requires_android =
1459        defined(invoker.requires_android) && invoker.requires_android
1460    _has_renaming_rules = defined(invoker.renaming_rules)
1461
1462    _is_java_target_name =
1463        filter_exclude([ target_name ], java_target_patterns) == []
1464    _target_name_without_java_or_junit =
1465        string_replace(string_replace(target_name, "_java", "_J"),
1466                       "_junit",
1467                       "_U")
1468    _zip_target_name = "${_target_name_without_java_or_junit}_zip"
1469    _zip_jar_path = invoker.output
1470
1471    if (_has_renaming_rules) {
1472      _zip_jar_path = "$target_gen_dir/$target_name.singlejar.jar"
1473
1474      # if we are java-like and have renaming rules, the main target is the
1475      # java_library_impl otherwise its the renaming target.
1476      if (_is_java_target_name) {
1477        _renaming_target_name = "${_target_name_without_java_or_junit}_renamed"
1478        _final_jar_target = _renaming_target_name
1479      } else {
1480        _renaming_target_name = target_name
1481      }
1482    } else {
1483      # If we dont have renaming rules then the main target is either the zip
1484      # target or the java_library_impl if we are java-like.
1485      if (_is_java_target_name) {
1486        _final_jar_target = _zip_target_name
1487      } else {
1488        _zip_target_name = target_name
1489      }
1490    }
1491
1492    _build_config = "$target_gen_dir/$target_name.build_config.json"
1493    _build_config_target_name = "$target_name$build_config_target_suffix"
1494    _build_config_dep = ":$_build_config_target_name"
1495
1496    if (_is_java_target_name) {
1497      # If we have a java-like target name we need to provide the expected
1498      # meta_targets as well as the processing (eg: ijar, bytecode rewriting)
1499      # that is expected of java targets so that other java targets can depend
1500      # on us.
1501      java_library_impl(target_name) {
1502        forward_variables_from(invoker,
1503                               [
1504                                 "jar_excluded_patterns",
1505                                 "deps",
1506                               ])
1507        type = "dist_jar"
1508        if (!defined(deps)) {
1509          deps = []
1510        }
1511        deps += [ ":$_final_jar_target" ]
1512
1513        supports_android = _supports_android
1514        requires_android = _requires_android
1515        jar_path = invoker.output
1516        enable_bytecode_checks = false
1517      }
1518    } else {
1519      write_build_config(_build_config_target_name) {
1520        type = "dist_jar"
1521        supports_android = _supports_android
1522        requires_android = _requires_android
1523        possible_config_deps = invoker.deps
1524        build_config = _build_config
1525      }
1526    }
1527
1528    _rebased_build_config = rebase_path(_build_config, root_build_dir)
1529    action_with_pydeps(_zip_target_name) {
1530      forward_variables_from(invoker, [ "data" ])
1531      script = "//build/android/gyp/zip.py"
1532      depfile = "$target_gen_dir/$target_name.d"
1533      deps = [ _build_config_dep ]
1534
1535      if (_use_interface_jars) {
1536        _lib_deps =
1537            filter_exclude(filter_include(invoker.deps, java_library_patterns),
1538                           java_resource_patterns)
1539        _other_deps = filter_exclude(invoker.deps, _lib_deps)
1540        foreach(_lib_dep, _lib_deps) {
1541          # Expand //foo/java -> //foo/java:java
1542          _lib_dep = get_label_info(_lib_dep, "label_no_toolchain")
1543          deps += [ "${_lib_dep}__header" ]
1544        }
1545        deps += _other_deps
1546      } else {
1547        deps += invoker.deps
1548      }
1549
1550      inputs = [ _build_config ]
1551
1552      outputs = [ _zip_jar_path ]
1553
1554      args = [
1555        "--depfile",
1556        rebase_path(depfile, root_build_dir),
1557        "--output",
1558        rebase_path(_zip_jar_path, root_build_dir),
1559        "--no-compress",
1560      ]
1561
1562      if (_direct_deps_only) {
1563        if (_use_interface_jars) {
1564          args += [ "--input-zips=@FileArg($_rebased_build_config:javac:interface_classpath)" ]
1565        } else if (_use_unprocessed_jars) {
1566          args += [
1567            "--input-zips=@FileArg($_rebased_build_config:javac:classpath)",
1568          ]
1569        } else {
1570          assert(
1571              false,
1572              "direct_deps_only does not work without use_interface_jars or use_unprocessed_jars")
1573        }
1574      } else {
1575        if (_use_interface_jars) {
1576          args += [ "--input-zips=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ]
1577        } else if (_use_unprocessed_jars) {
1578          args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ]
1579        } else {
1580          args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:device_classpath)" ]
1581        }
1582      }
1583
1584      _excludes = []
1585      if (defined(invoker.jar_excluded_patterns)) {
1586        _excludes += invoker.jar_excluded_patterns
1587      }
1588      if (_use_interface_jars) {
1589        # Turbine adds files like: META-INF/TRANSITIVE/.../Foo.class
1590        # These confuse proguard: https://crbug.com/1081443
1591        _excludes += [ "META-INF/*" ]
1592      } else {
1593        # Manifest files will never be correct when merging jars.
1594        _excludes += [ "META-INF/*.MF" ]
1595      }
1596      if (_excludes != []) {
1597        args += [ "--input-zips-excluded-globs=$_excludes" ]
1598      }
1599    }
1600
1601    if (_has_renaming_rules) {
1602      rename_jar_classes(_renaming_target_name) {
1603        input = _zip_jar_path
1604        output = invoker.output
1605        deps = [ ":$_zip_target_name" ]
1606        renaming_rules = invoker.renaming_rules
1607      }
1608    }
1609  }
1610
1611  # Combines all dependent .jar files into a single proguarded .dex file.
1612  #
1613  # Variables:
1614  #   output: Path to the output .dex or .dex.jar.
1615  #   proguard_enabled: Whether to enable R8.
1616  #   proguard_configs: List of proguard configs.
1617  #   proguard_enable_obfuscation: Whether to enable obfuscation (default=true).
1618  #   package_name: Used in the Proguard map ID.
1619  #   version_code: Used in the Proguard map ID.
1620  #
1621  # Example
1622  #   dist_dex("lib_fatjar") {
1623  #     deps = [ ":my_java_lib" ]
1624  #     output = "$root_build_dir/MyLibrary.jar"
1625  #   }
1626  template("dist_dex") {
1627    _deps = [ default_android_sdk_dep ]
1628    if (defined(invoker.deps)) {
1629      _deps += invoker.deps
1630    }
1631
1632    _build_config = "$target_gen_dir/$target_name.build_config.json"
1633    _build_config_target_name = "$target_name$build_config_target_suffix"
1634
1635    write_build_config(_build_config_target_name) {
1636      type = "dist_jar"
1637      forward_variables_from(invoker,
1638                             [
1639                               "proguard_configs",
1640                               "proguard_enabled",
1641                             ])
1642      supports_android = true
1643      requires_android = true
1644      possible_config_deps = _deps
1645      build_config = _build_config
1646    }
1647
1648    dex(target_name) {
1649      forward_variables_from(invoker,
1650                             TESTONLY_AND_VISIBILITY + [
1651                                   "data",
1652                                   "data_deps",
1653                                   "package_name",
1654                                   "proguard_configs",
1655                                   "proguard_enabled",
1656                                   "proguard_enable_obfuscation",
1657                                   "min_sdk_version",
1658                                   "repackage_classes",
1659                                   "version_code",
1660                                 ])
1661      deps = [ ":$_build_config_target_name" ] + _deps
1662      build_config = _build_config
1663      output = invoker.output
1664      if (defined(proguard_enabled) && proguard_enabled) {
1665        # The individual dependencies would have caught real missing deps in
1666        # their respective dex steps. False positives that were suppressed at
1667        # per-target dex steps are emitted here since this is using jar files
1668        # rather than dex files.
1669        ignore_desugar_missing_deps = true
1670      } else {
1671        _rebased_build_config = rebase_path(_build_config, root_build_dir)
1672        input_dex_filearg =
1673            "@FileArg(${_rebased_build_config}:deps_info:all_dex_files)"
1674      }
1675    }
1676  }
1677
1678  # Creates an Android .aar library.
1679  #
1680  # Currently supports:
1681  #   * AndroidManifest.xml
1682  #   * classes.jar
1683  #   * jni/
1684  #   * res/
1685  #   * R.txt
1686  #   * proguard.txt
1687  # Does not yet support:
1688  #   * public.txt
1689  #   * annotations.zip
1690  #   * assets/
1691  # See: https://developer.android.com/studio/projects/android-library.html#aar-contents
1692  #
1693  # Variables:
1694  #   output: Path to the output .aar.
1695  #   proguard_configs: List of proguard configs (optional).
1696  #   android_manifest: Path to AndroidManifest.xml (optional).
1697  #   native_libraries: list of native libraries (optional).
1698  #   direct_deps_only: Do not recurse on deps (optional, defaults false).
1699  #   jar_excluded_patterns: List of globs for paths to exclude (optional).
1700  #   jar_included_patterns: List of globs for paths to include (optional).
1701  #
1702  # Example
1703  #   dist_aar("my_aar") {
1704  #     deps = [ ":my_java_lib" ]
1705  #     output = "$root_build_dir/MyLibrary.aar"
1706  #   }
1707  template("dist_aar") {
1708    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1709
1710    _direct_deps_only =
1711        defined(invoker.direct_deps_only) && invoker.direct_deps_only
1712
1713    _deps = []
1714
1715    if (defined(invoker.deps)) {
1716      _deps += invoker.deps
1717    }
1718
1719    _build_config = "$target_gen_dir/$target_name.build_config.json"
1720    _build_config_target_name = "$target_name$build_config_target_suffix"
1721
1722    write_build_config(_build_config_target_name) {
1723      type = "dist_aar"
1724      forward_variables_from(invoker, [ "proguard_configs" ])
1725      possible_config_deps = _deps
1726      supports_android = true
1727      requires_android = true
1728      build_config = _build_config
1729    }
1730
1731    _deps += [ ":$_build_config_target_name" ]
1732
1733    _rebased_build_config = rebase_path(_build_config, root_build_dir)
1734
1735    action_with_pydeps(target_name) {
1736      forward_variables_from(invoker,
1737                             [
1738                               "data",
1739                               "assert_no_deps",
1740                             ])
1741      depfile = "$target_gen_dir/$target_name.d"
1742      deps = _deps
1743      script = "//build/android/gyp/dist_aar.py"
1744
1745      inputs = [ _build_config ]
1746
1747      # Although these will be listed as deps in the depfile, they must also
1748      # appear here so that "gn analyze" knows about them.
1749      # https://crbug.com/827197
1750      if (defined(invoker.proguard_configs)) {
1751        inputs += invoker.proguard_configs
1752      }
1753
1754      outputs = [ invoker.output ]
1755
1756      args = [
1757        "--depfile",
1758        rebase_path(depfile, root_build_dir),
1759        "--output",
1760        rebase_path(invoker.output, root_build_dir),
1761        "--dependencies-res-zips=@FileArg($_rebased_build_config:deps_info:dependency_zips)",
1762        "--r-text-files=@FileArg($_rebased_build_config:deps_info:dependency_r_txt_files)",
1763        "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)",
1764      ]
1765      if (_direct_deps_only) {
1766        args += [ "--jars=@FileArg($_rebased_build_config:javac:classpath)" ]
1767      } else {
1768        args += [
1769          "--jars=@FileArg($_rebased_build_config:deps_info:device_classpath)",
1770        ]
1771      }
1772
1773      if (defined(invoker.android_manifest)) {
1774        args += [
1775          "--android-manifest",
1776          rebase_path(invoker.android_manifest, root_build_dir),
1777        ]
1778      }
1779      if (defined(invoker.native_libraries) && invoker.native_libraries != []) {
1780        inputs += invoker.native_libraries
1781        _rebased_native_libraries =
1782            rebase_path(invoker.native_libraries, root_build_dir)
1783
1784        args += [
1785          "--native-libraries=$_rebased_native_libraries",
1786          "--abi=$android_app_abi",
1787        ]
1788      }
1789      if (defined(invoker.jar_excluded_patterns)) {
1790        args += [ "--jar-excluded-globs=${invoker.jar_excluded_patterns}" ]
1791      }
1792      if (defined(invoker.jar_included_patterns)) {
1793        args += [ "--jar-included-globs=${invoker.jar_included_patterns}" ]
1794      }
1795      if (defined(invoker.resource_included_patterns)) {
1796        args += [
1797          "--resource-included-globs=${invoker.resource_included_patterns}",
1798        ]
1799      }
1800    }
1801  }
1802
1803  # Declare an Android library target
1804  #
1805  # This target creates an Android library containing java code and Android
1806  # resources.
1807  #
1808  # Supports all variables of java_library(), plus:
1809  #   deps: In addition to defining java deps, this can also include
1810  #     android_assets() and android_resources() targets.
1811  #   alternative_android_sdk_dep: android_system_java_prebuilt target to use
1812  #     in place of the default android.jar.
1813  #
1814  # Example
1815  #   android_library("foo_java") {
1816  #     sources = [
1817  #       "android/org/chromium/foo/Foo.java",
1818  #       "android/org/chromium/foo/FooInterface.java",
1819  #       "android/org/chromium/foo/FooService.java",
1820  #     ]
1821  #     deps = [
1822  #       ":bar_java"
1823  #     ]
1824  #     srcjar_deps = [
1825  #       ":foo_generated_enum"
1826  #     ]
1827  #     jar_excluded_patterns = [
1828  #       "*/FooService.class", "org/chromium/FooService\$*.class"
1829  #     ]
1830  #   }
1831  template("android_library") {
1832    java_library(target_name) {
1833      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
1834      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1835
1836      supports_android = true
1837      requires_android = true
1838
1839      if (!defined(jar_excluded_patterns)) {
1840        jar_excluded_patterns = []
1841      }
1842      jar_excluded_patterns += [
1843        "*/R.class",
1844        "*/R\$*.class",
1845        "*/Manifest.class",
1846        "*/Manifest\$*.class",
1847        "*/*GEN_JNI.class",
1848      ]
1849    }
1850  }
1851
1852  # Declare an Android robolectric library target
1853  #
1854  # This target creates an Android library containing java code and Android
1855  # resources.
1856  #
1857  # Supports all variables of java_library(), plus:
1858  #   deps: In addition to defining java deps, this can also include
1859  #     android_assets() and android_resources() targets.
1860  #
1861  # Example
1862  #   robolectric_library("foo_junit") {
1863  #     sources = [
1864  #       "android/org/chromium/foo/FooTest.java",
1865  #       "android/org/chromium/foo/FooTestUtils.java",
1866  #       "android/org/chromium/foo/FooMock.java",
1867  #     ]
1868  #     deps = [
1869  #       "//base:base_junit_test_support"
1870  #     ]
1871  #     srcjar_deps = [
1872  #       ":foo_generated_enum"
1873  #     ]
1874  #     jar_excluded_patterns = [
1875  #       "*/FooService.class", "org/chromium/FooService\$*.class"
1876  #     ]
1877  #   }
1878  template("robolectric_library") {
1879    java_library(target_name) {
1880      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
1881      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1882
1883      testonly = true
1884
1885      is_robolectric = true
1886      include_android_sdk = true
1887      alternative_android_sdk_dep =
1888          "//third_party/robolectric:robolectric_test_sdk_java"
1889
1890      if (!defined(jar_excluded_patterns)) {
1891        jar_excluded_patterns = []
1892      }
1893      jar_excluded_patterns += [
1894        "*/R.class",
1895        "*/R\$*.class",
1896        "*/Manifest.class",
1897        "*/Manifest\$*.class",
1898        "*/*GEN_JNI.class",
1899      ]
1900
1901      if (!defined(deps)) {
1902        deps = []
1903      }
1904      deps += [ "//third_party/android_deps:robolectric_all_java" ]
1905    }
1906  }
1907
1908  # Declare an Android library target for a prebuilt jar
1909  #
1910  # This target creates an Android library containing java code and Android
1911  # resources.
1912  #
1913  # Supports all variables of android_library().
1914  #
1915  # Example
1916  #   android_java_prebuilt("foo_java") {
1917  #     jar_path = "foo.jar"
1918  #     deps = [
1919  #       ":foo_resources",
1920  #       ":bar_java"
1921  #     ]
1922  #   }
1923  template("android_java_prebuilt") {
1924    android_library(target_name) {
1925      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
1926      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1927    }
1928  }
1929
1930  template("android_system_java_prebuilt") {
1931    java_library_impl(target_name) {
1932      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
1933      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1934      supports_android = true
1935      type = "system_java_library"
1936    }
1937  }
1938
1939  # Creates org/chromium/build/BuildConfig.java
1940  template("generate_build_config_srcjar") {
1941    java_cpp_template(target_name) {
1942      forward_variables_from(invoker,
1943                             TESTONLY_AND_VISIBILITY + [
1944                                   "deps",
1945                                   "inputs",
1946                                 ])
1947      sources = [ "//build/android/java/templates/BuildConfig.template" ]
1948      defines = []
1949
1950      if ((defined(invoker.assertions_implicitly_enabled) &&
1951           invoker.assertions_implicitly_enabled) || enable_java_asserts) {
1952        defines += [ "_ENABLE_ASSERTS" ]
1953      }
1954      if (use_cfi_diag || is_ubsan_any) {
1955        defines += [ "_IS_UBSAN" ]
1956      }
1957
1958      if (is_chrome_branded) {
1959        defines += [ "_IS_CHROME_BRANDED" ]
1960      }
1961
1962      if (defined(invoker.is_bundle) && invoker.is_bundle) {
1963        defines += [ "_IS_BUNDLE" ]
1964      }
1965
1966      if (defined(invoker.isolated_splits_enabled) &&
1967          invoker.isolated_splits_enabled) {
1968        defines += [ "_ISOLATED_SPLITS_ENABLED" ]
1969      }
1970
1971      if (defined(invoker.is_incremental_install) &&
1972          invoker.is_incremental_install) {
1973        defines += [ "_IS_INCREMENTAL_INSTALL" ]
1974      }
1975
1976      if (defined(invoker.min_sdk_version)) {
1977        defines += [ "_MIN_SDK_VERSION=${invoker.min_sdk_version}" ]
1978      } else {
1979        defines += [ "_MIN_SDK_VERSION=$default_min_sdk_version" ]
1980      }
1981      if (defined(invoker.version_code)) {
1982        defines += [ "_VERSION_CODE=${invoker.version_code}" ]
1983      } else {
1984        defines += [ "_VERSION_CODE=$android_default_version_code" ]
1985      }
1986      if (defined(invoker.resources_version_variable)) {
1987        defines += [
1988          "_RESOURCES_VERSION_VARIABLE=${invoker.resources_version_variable}",
1989        ]
1990      }
1991      if (defined(invoker.apk_assets_suffixed_list)) {
1992        defines += [
1993          "_APK_ASSETS_SUFFIXED_LIST=${invoker.apk_assets_suffixed_list}",
1994          "_APK_ASSETS_SUFFIX=${invoker.apk_assets_suffix}",
1995        ]
1996      }
1997
1998      _test_only = defined(testonly) && testonly
1999      if (_test_only) {
2000        defines += [ "_IS_FOR_TEST" ]
2001      }
2002
2003      if (!is_java_debug && (!_test_only || is_cronet_build)) {
2004        defines += [ "_DISABLE_DEBUG_LOGS" ]
2005      }
2006
2007      if (is_cronet_build) {
2008        defines += [ "_IS_CRONET_BUILD" ]
2009        defines += [ "_LOGTAG_PREFIX=cn_" ]
2010      } else {
2011        defines += [ "_LOGTAG_PREFIX=cr_" ]
2012      }
2013      if (is_desktop_android) {
2014        defines += [ "_IS_DESKTOP_ANDROID" ]
2015      }
2016
2017      if (defined(invoker.write_clang_profiling_data) &&
2018          invoker.write_clang_profiling_data) {
2019        defines += [ "_WRITE_CLANG_PROFILING_DATA" ]
2020      }
2021
2022      if (defined(invoker.disable_strict_mode_context) &&
2023          invoker.disable_strict_mode_context) {
2024        defines += [ "_DISABLE_STRICT_MODE_CONTEXT" ]
2025      }
2026    }
2027  }
2028
2029  # Creates ProductConfig.java, a file containing product-specific configuration.
2030  #
2031  # Currently, this includes the list of locales, both in their compressed and
2032  # uncompressed format, as well as library loading
2033  #
2034  # Variables:
2035  #   build_config: Path to build_config used for locale lists.
2036  #   java_package: Java package for the generated class.
2037  #   use_chromium_linker:
2038  template("generate_product_config_srcjar") {
2039    java_cpp_template(target_name) {
2040      defines = []
2041      _use_final =
2042          defined(invoker.build_config) ||
2043          defined(invoker.use_chromium_linker) || defined(invoker.is_bundle)
2044      if (_use_final) {
2045        defines += [ "USE_FINAL" ]
2046      }
2047
2048      sources = [ "//build/android/java/templates/ProductConfig.template" ]
2049      defines += [ "PACKAGE=${invoker.java_package}" ]
2050
2051      _use_chromium_linker =
2052          defined(invoker.use_chromium_linker) && invoker.use_chromium_linker
2053      defines += [ "USE_CHROMIUM_LINKER_VALUE=$_use_chromium_linker" ]
2054      if (defined(invoker.build_config)) {
2055        forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
2056        _rebased_build_config =
2057            rebase_path(invoker.build_config, root_build_dir)
2058        defines += [ "LOCALE_LIST=@FileArg($_rebased_build_config:deps_info:locales_java_list)" ]
2059      }
2060    }
2061  }
2062
2063  # Declare an Android app module target, which is used as the basis for an
2064  # Android APK or an Android app bundle module.
2065  #
2066  # Supports all variables of android_library(), plus:
2067  #   android_manifest: Path to AndroidManifest.xml. NOTE: This manifest must
2068  #     not contain a <uses-sdk> element. Use [min|target|max]_sdk_version
2069  #     instead.
2070  #   android_manifest_dep: Target that generates AndroidManifest (if applicable)
2071  #   png_to_webp: If true, pngs (with the exception of 9-patch) are
2072  #     converted to webp during resource packaging.
2073  #   loadable_modules: List of paths to native libraries to include. Different
2074  #     from |shared_libraries| in that:
2075  #       * dependencies of this .so are not automatically included
2076  #       * they are not side-loaded when incremental_install=true.
2077  #       * they are not included in NativeLibraries.java
2078  #     Use this instead of shared_libraries when you are going to load the library
2079  #     conditionally, and only when shared_libraries doesn't work for you.
2080  #   secondary_abi_loadable_modules: This is the loadable_modules analog to
2081  #     secondary_abi_shared_libraries.
2082  #   shared_libraries: List shared_library targets to bundle. If these
2083  #     libraries depend on other shared_library targets, those dependencies will
2084  #     also be included in the apk (e.g. for is_component_build).
2085  #   secondary_abi_shared_libraries: secondary abi shared_library targets to
2086  #     bundle. If these libraries depend on other shared_library targets, those
2087  #     dependencies will also be included in the apk (e.g. for is_component_build).
2088  #   native_lib_placeholders: List of placeholder filenames to add to the apk
2089  #     (optional).
2090  #   secondary_native_lib_placeholders: List of placeholder filenames to add to
2091  #     the apk for the secondary ABI (optional).
2092  #   generate_buildconfig_java: If defined and false, skip generating the
2093  #     BuildConfig java class describing the build configuration. The default
2094  #     is true when building with Chromium for non-test APKs.
2095  #   generate_native_libraries_java: If defined, whether NativeLibraries.java is
2096  #     generated is solely controlled by this flag. Otherwise, the default behavior
2097  #     is NativeLibraries.java will only be generated for the base module/apk when
2098  #     its `shared_libraries` is not empty.
2099  #   aapt_locale_allowlist: If set, all locales not in this list will be
2100  #     stripped from resources.arsc.
2101  #   resource_exclusion_regex: Causes all drawable images matching the regex to
2102  #     be excluded (mipmaps are still included).
2103  #   resource_exclusion_exceptions: A list of globs used when
2104  #     resource_exclusion_regex is set. Files that match this list will
2105  #     still be included.
2106  #   resource_values_filter_rules: List of "source_path:name_regex" used to
2107  #     filter out unwanted values/ resources.
2108  #   shared_resources: True if this is a runtime shared library APK, like
2109  #     the system_webview_apk target. Ensures that its resources can be
2110  #     used by the loading application process.
2111  #   app_as_shared_lib: True if this is a regular application apk that can
2112  #     also serve as a runtime shared library, like the monochrome_public_apk
2113  #     target. Ensures that the resources are usable both by the APK running
2114  #     as an application, or by another process that loads it at runtime.
2115  #   shared_resources_allowlist_target: Optional name of a target specifying
2116  #     an input R.txt file that lists the resources that can be exported
2117  #     by the APK when shared_resources or app_as_shared_lib is defined.
2118  #   uncompress_dex: Store final .dex files uncompressed in the apk.
2119  #   omit_dex: If true, do not build or include classes.dex.
2120  #   strip_resource_names: True if resource names should be stripped from the
2121  #     resources.arsc file in the apk or module.
2122  #   strip_unused_resources: True if unused resources should be stripped from
2123  #     the apk or module.
2124  #   short_resource_paths: True if resource paths should be shortened in the
2125  #     apk or module.
2126  #   resources_config_paths: List of paths to the aapt2 optimize config files
2127  #     that tags resources with acceptable/non-acceptable optimizations.
2128  #   expected_android_manifest: Enables verification of expected merged
2129  #     manifest based on a golden file.
2130  #   resource_ids_provider_dep: If passed, this target will use the resource
2131  #     IDs generated by {resource_ids_provider_dep}__compile_res during
2132  #     resource compilation.
2133  #   enforce_resource_overlays_in_tests: Enables check for testonly targets that
2134  #     dependent resource targets which override another target set
2135  #     overlay_resources=true. This check is on for non-test targets and
2136  #     cannot be disabled.
2137  #   static_library_provider: Specifies a single target that this target will
2138  #     use as a static library APK.
2139  #   min_sdk_version: The minimum Android SDK version this target supports.
2140  #     Optional, default $default_min_sdk_version.
2141  #   target_sdk_version: The target Android SDK version for this target.
2142  #     Optional, default to default_target_sdk_version.
2143  #   max_sdk_version: The maximum Android SDK version this target supports.
2144  #     Optional, default not set.
2145  #   require_native_mocks: Enforce that any native calls using
2146  #     org.chromium.base.annotations.NativeMethods must have a mock set
2147  #     (optional).
2148  #   product_config_java_packages: Optional list of java packages. If given, a
2149  #     ProductConfig.java file will be generated for each package.
2150  #   enable_proguard_checks: Turns on -checkdiscard directives and missing
2151  #     symbols check in the proguard step (default=true).
2152  #   annotation_processor_deps: List of java_annotation_processor targets to
2153  #     use when compiling the sources given to this target (optional).
2154  #   processor_args_javac: List of args to pass to annotation processors when
2155  #     compiling sources given to this target (optional).
2156  #   bundles_supported: Enable Java code to treat this target as a bundle
2157  #     whether (by default determined by the target type).
2158  #   expected_libs_and_assets: Verify the list of included native libraries
2159  #     and assets is consistent with the given expectation file.
2160  #   expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff
2161  #     with this file as the base.
2162  #   expected_proguard_config: Checks that the merged set of proguard flags
2163  #     matches the given config.
2164  #   expected_proguard_config_base: Treat expected_proguard_config as a diff
2165  #     with this file as the base.
2166  #   suffix_apk_assets_used_by: Prefixes android assets used by the given apk
2167  #     with $package_name. Adds the list of renamed packages to
2168  #     BuildConfig.java.
2169  template("android_apk_or_module") {
2170    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
2171    _template_name = target_name
2172    _base_path = "$target_out_dir/$target_name/$target_name"
2173    _build_config = "$target_gen_dir/$target_name.build_config.json"
2174    _build_config_target = "$target_name$build_config_target_suffix"
2175    _java_target_name = "${_template_name}__java"
2176
2177    _min_sdk_version = default_min_sdk_version
2178    _target_sdk_version = default_target_sdk_version
2179    if (defined(invoker.min_sdk_version)) {
2180      _min_sdk_version = invoker.min_sdk_version
2181    }
2182    if (is_asan && _min_sdk_version < min_supported_sdk_version) {
2183      _min_sdk_version = min_supported_sdk_version
2184    }
2185    if (defined(invoker.target_sdk_version)) {
2186      _target_sdk_version = invoker.target_sdk_version
2187    }
2188
2189    _is_bundle_module =
2190        defined(invoker.is_bundle_module) && invoker.is_bundle_module
2191    _is_base_module = !_is_bundle_module || (defined(invoker.is_base_module) &&
2192                                             invoker.is_base_module)
2193
2194    _omit_dex = defined(invoker.omit_dex) && invoker.omit_dex
2195
2196    if (!_is_bundle_module) {
2197      _final_apk_path = invoker.final_apk_path
2198      _final_rtxt_path = "${_final_apk_path}.R.txt"
2199    }
2200
2201    _res_size_info_path = "$target_out_dir/$target_name.ap_.info"
2202    if (!_is_bundle_module) {
2203      _final_apk_path_no_ext_list =
2204          process_file_template([ _final_apk_path ],
2205                                "{{source_dir}}/{{source_name_part}}")
2206      _final_apk_path_no_ext = _final_apk_path_no_ext_list[0]
2207      not_needed([ "_final_apk_path_no_ext" ])
2208    }
2209
2210    # Non-base bundle modules create only proto resources.
2211    if (_is_base_module) {
2212      _arsc_resources_path = "$target_out_dir/$target_name.ap_"
2213    }
2214    if (_is_bundle_module) {
2215      # Path to the intermediate proto-format resources zip file.
2216      _proto_resources_path = "$target_out_dir/$target_name.proto.ap_"
2217    } else {
2218      # resource_sizes.py needs to be able to find the unpacked resources.arsc
2219      # file based on apk name to compute normatlized size.
2220      _resource_sizes_arsc_path =
2221          "$root_out_dir/arsc/" +
2222          rebase_path(_final_apk_path_no_ext, root_build_dir) + ".ap_"
2223    }
2224
2225    if (defined(invoker.version_code)) {
2226      _version_code = invoker.version_code
2227    } else {
2228      _version_code = android_default_version_code
2229    }
2230
2231    if (android_override_version_code != "") {
2232      _version_code = android_override_version_code
2233    }
2234
2235    if (defined(invoker.version_name)) {
2236      _version_name = invoker.version_name
2237    } else {
2238      _version_name = android_default_version_name
2239    }
2240
2241    if (android_override_version_name != "") {
2242      _version_name = android_override_version_name
2243    }
2244
2245    if (defined(invoker.deps)) {
2246      _invoker_deps = invoker.deps
2247    } else {
2248      _invoker_deps = []
2249    }
2250    _non_java_deps = filter_exclude(_invoker_deps, java_target_patterns)
2251    _java_assetres_deps = [ ":${_java_target_name}__assetres" ]
2252
2253    _srcjar_deps = []
2254    if (defined(invoker.srcjar_deps)) {
2255      _srcjar_deps = invoker.srcjar_deps
2256    }
2257
2258    _use_chromium_linker =
2259        defined(invoker.use_chromium_linker) && invoker.use_chromium_linker
2260
2261    not_needed([ "_use_chromium_linker" ])
2262
2263    # The dependency that makes the chromium linker, if any is needed.
2264    _native_libs_deps = []
2265    _shared_libraries_is_valid =
2266        defined(invoker.shared_libraries) && invoker.shared_libraries != []
2267
2268    if (_shared_libraries_is_valid) {
2269      _native_libs_deps += invoker.shared_libraries
2270
2271      # Write shared library output files of all dependencies to a file. Those
2272      # will be the shared libraries packaged into the APK.
2273      _shared_library_list_file =
2274          "$target_gen_dir/${_template_name}.native_libs"
2275      generated_file("${_template_name}__shared_library_list") {
2276        deps = _native_libs_deps
2277        outputs = [ _shared_library_list_file ]
2278        data_keys = [ "shared_libraries" ]
2279        walk_keys = [ "shared_libraries_barrier" ]
2280        rebase = root_build_dir
2281      }
2282    } else {
2283      # Must exist for instrumentation_test_apk() to depend on.
2284      group("${_template_name}__shared_library_list") {
2285      }
2286    }
2287
2288    _secondary_abi_native_libs_deps = []
2289
2290    if (defined(invoker.secondary_abi_shared_libraries) &&
2291        invoker.secondary_abi_shared_libraries != []) {
2292      _secondary_abi_native_libs_deps = invoker.secondary_abi_shared_libraries
2293
2294      # Write shared library output files of all dependencies to a file. Those
2295      # will be the shared libraries packaged into the APK.
2296      _secondary_abi_shared_library_list_file =
2297          "$target_gen_dir/${_template_name}.secondary_abi_native_libs"
2298      generated_file("${_template_name}__secondary_abi_shared_library_list") {
2299        deps = _secondary_abi_native_libs_deps
2300        outputs = [ _secondary_abi_shared_library_list_file ]
2301        data_keys = [ "shared_libraries" ]
2302        walk_keys = [ "shared_libraries_barrier" ]
2303        rebase = root_build_dir
2304      }
2305    } else {
2306      # Must exist for instrumentation_test_apk() to depend on.
2307      group("${_template_name}__secondary_abi_shared_library_list") {
2308      }
2309    }
2310
2311    _rebased_build_config = rebase_path(_build_config, root_build_dir)
2312    assert(_rebased_build_config != "")  # Mark as used.
2313
2314    _generate_productconfig_java =
2315        defined(invoker.product_config_java_packages) && !_omit_dex
2316
2317    _proguard_enabled =
2318        defined(invoker.proguard_enabled) && invoker.proguard_enabled
2319
2320    if (!_is_bundle_module && _proguard_enabled) {
2321      _proguard_mapping_path = "$_final_apk_path.mapping"
2322    }
2323
2324    if (defined(invoker.resource_ids_provider_dep)) {
2325      _resource_ids_provider_dep = invoker.resource_ids_provider_dep
2326    }
2327
2328    if (defined(invoker.shared_resources_allowlist_target)) {
2329      _shared_resources_allowlist_target =
2330          invoker.shared_resources_allowlist_target
2331    }
2332
2333    _uses_static_library = defined(invoker.static_library_provider)
2334
2335    # TODO(crbug.com/40585188): Allow incremental installs of bundle modules.
2336    _incremental_apk =
2337        !_is_bundle_module &&
2338        !(defined(invoker.never_incremental) && invoker.never_incremental) &&
2339        incremental_install && _min_sdk_version >= default_min_sdk_version
2340    if (_incremental_apk) {
2341      _target_dir_name = get_label_info(target_name, "dir")
2342      _incremental_install_json_path = "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.incremental.json"
2343      _incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk"
2344    }
2345
2346    if (!_incremental_apk && !_omit_dex) {
2347      # Bundle modules don't build the dex here, but need to write this path
2348      # to their .build_config.json file only when proguarding.
2349      if (_proguard_enabled) {
2350        _final_dex_path = "$_base_path.r8dex.jar"
2351      } else if (!_is_bundle_module) {
2352        _final_dex_path = "$_base_path.mergeddex.jar"
2353      }
2354    }
2355
2356    _android_manifest =
2357        "$target_gen_dir/${_template_name}/AndroidManifest.merged.xml"
2358    _merge_manifest_target = "${_template_name}__merge_manifests"
2359    merge_manifests(_merge_manifest_target) {
2360      forward_variables_from(invoker,
2361                             [
2362                               "manifest_package",
2363                               "max_sdk_version",
2364                             ])
2365      input_manifest = invoker.android_manifest
2366      output_manifest = _android_manifest
2367      build_config = _build_config
2368      min_sdk_version = _min_sdk_version
2369      target_sdk_version = _target_sdk_version
2370
2371      # Depend on android_resources() targets that use generated files
2372      # in mergeable_android_manifests (such as android_aar_prebuilt).
2373      deps = _java_assetres_deps + [ ":$_build_config_target" ]
2374      if (defined(invoker.android_manifest_dep)) {
2375        deps += [ invoker.android_manifest_dep ]
2376      }
2377    }
2378
2379    _final_deps = [ ":$_java_target_name" ]
2380
2381    _generated_proguard_config = "$_base_path.resources.proguard.txt"
2382
2383    if (defined(_shared_resources_allowlist_target)) {
2384      _allowlist_gen_dir =
2385          get_label_info(_shared_resources_allowlist_target, "target_gen_dir")
2386      _allowlist_target_name =
2387          get_label_info(_shared_resources_allowlist_target, "name")
2388      _allowlist_r_txt_path =
2389          "${_allowlist_gen_dir}/${_allowlist_target_name}" +
2390          "__compile_resources_R.txt"
2391      _allowlist_deps =
2392          "${_shared_resources_allowlist_target}__compile_resources"
2393    }
2394
2395    if (_incremental_apk) {
2396      _incremental_android_manifest =
2397          "$target_gen_dir/${_template_name}/AndroidManifest.incremental.xml"
2398      _incremental_manifest_target_name = "${target_name}__incremental_manifest"
2399      action_with_pydeps(_incremental_manifest_target_name) {
2400        deps = [ ":$_merge_manifest_target" ]
2401        script =
2402            "//build/android/incremental_install/generate_android_manifest.py"
2403        inputs = [ _android_manifest ]
2404        outputs = [ _incremental_android_manifest ]
2405
2406        args = [
2407          "--disable-isolated-processes",
2408          "--src-manifest",
2409          rebase_path(_android_manifest, root_build_dir),
2410          "--dst-manifest",
2411          rebase_path(_incremental_android_manifest, root_build_dir),
2412        ]
2413      }
2414    }
2415
2416    _compile_resources_target = "${_template_name}__compile_resources"
2417    _compile_resources_rtxt_out =
2418        "${target_gen_dir}/${_compile_resources_target}_R.txt"
2419    _compile_resources_emit_ids_out =
2420        "${target_gen_dir}/${_compile_resources_target}.resource_ids"
2421    compile_resources(_compile_resources_target) {
2422      forward_variables_from(
2423          invoker,
2424          [
2425            "aapt_locale_allowlist",
2426            "app_as_shared_lib",
2427            "enforce_resource_overlays_in_tests",
2428            "expected_android_manifest",
2429            "expected_android_manifest_base",
2430            "expected_android_manifest_library_version_offset",
2431            "expected_android_manifest_version_code_offset",
2432            "manifest_package",
2433            "max_sdk_version",
2434            "override_target_sdk",
2435            "package_id",
2436            "png_to_webp",
2437            "r_java_root_package_name",
2438            "resource_exclusion_exceptions",
2439            "resource_exclusion_regex",
2440            "resource_values_filter_rules",
2441            "shared_resources",
2442            "shared_resources_allowlist_locales",
2443            "uses_split",
2444          ])
2445      android_manifest = _android_manifest
2446      android_manifest_dep = ":$_merge_manifest_target"
2447      version_code = _version_code
2448      version_name = _version_name
2449      min_sdk_version = _min_sdk_version
2450      target_sdk_version = _target_sdk_version
2451
2452      if (defined(expected_android_manifest)) {
2453        top_target_name = _template_name
2454      }
2455
2456      if (defined(_resource_ids_provider_dep)) {
2457        resource_ids_provider_dep = _resource_ids_provider_dep
2458      }
2459
2460      if (defined(invoker.module_name)) {
2461        package_name = invoker.module_name
2462      }
2463
2464      if (defined(invoker.post_process_package_resources_script)) {
2465        post_process_script = invoker.post_process_package_resources_script
2466      }
2467      r_text_out_path = _compile_resources_rtxt_out
2468      emit_ids_out_path = _compile_resources_emit_ids_out
2469      size_info_path = _res_size_info_path
2470      proguard_file = _generated_proguard_config
2471
2472      build_config = _build_config
2473      build_config_dep = ":$_build_config_target"
2474      deps = _java_assetres_deps + _non_java_deps
2475
2476      if (_incremental_apk) {
2477        android_manifest = _incremental_android_manifest
2478        android_manifest_dep = ":$_incremental_manifest_target_name"
2479      }
2480
2481      if (defined(invoker.apk_under_test)) {
2482        # Set the arsc package name to match the apk_under_test package name
2483        # So that test resources can references under_test resources via
2484        # @type/name syntax.
2485        r_java_root_package_name = "test"
2486        arsc_package_name =
2487            "@FileArg($_rebased_build_config:deps_info:arsc_package_name)"
2488
2489        # Passing in the --emit-ids mapping will cause aapt2 to assign resources
2490        # IDs that do not conflict with those from apk_under_test.
2491        assert(!defined(resource_ids_provider_dep))
2492        resource_ids_provider_dep = invoker.apk_under_test
2493
2494        _link_against = invoker.apk_under_test
2495      }
2496
2497      if (_is_bundle_module) {
2498        is_bundle_module = true
2499        proto_output = _proto_resources_path
2500
2501        if (defined(invoker.base_module_target)) {
2502          _link_against = invoker.base_module_target
2503        }
2504      }
2505
2506      if (defined(_link_against)) {
2507        deps += [ "${_link_against}__compile_resources" ]
2508        include_resource = get_label_info(_link_against, "target_out_dir") +
2509                           "/" + get_label_info(_link_against, "name") + ".ap_"
2510      }
2511
2512      # Bundle modules have to reference resources from the base module.
2513      if (_is_base_module) {
2514        arsc_output = _arsc_resources_path
2515      }
2516
2517      if (defined(_shared_resources_allowlist_target)) {
2518        # Used to ensure that the WebView resources are properly shared
2519        # (i.e. are non-final and with package ID 0).
2520        shared_resources_allowlist = _allowlist_r_txt_path
2521        deps += [ _allowlist_deps ]
2522      }
2523    }
2524    _srcjar_deps += [ ":$_compile_resources_target" ]
2525
2526    _short_resource_paths =
2527        defined(invoker.short_resource_paths) && invoker.short_resource_paths &&
2528        enable_arsc_obfuscation
2529    _strip_resource_names =
2530        defined(invoker.strip_resource_names) && invoker.strip_resource_names &&
2531        enable_arsc_obfuscation
2532    _strip_unused_resources =
2533        defined(invoker.strip_unused_resources) &&
2534        invoker.strip_unused_resources && enable_unused_resource_stripping
2535    _optimize_resources = _strip_resource_names || _short_resource_paths ||
2536                          _strip_unused_resources
2537
2538    if (_strip_unused_resources) {
2539      # These need to be kept in sync with the target names + output paths
2540      # in the android_app_bundle template.
2541      _unused_resources_target = "${_template_name}__unused_resources"
2542      _unused_resources_config_path =
2543          "$target_gen_dir/${_template_name}_unused_resources.config"
2544    }
2545
2546    if (_optimize_resources) {
2547      if (_is_bundle_module) {
2548        _optimized_proto_resources_path =
2549            "$target_out_dir/$target_name.optimized.proto.ap_"
2550      } else {
2551        _optimized_arsc_resources_path =
2552            "$target_out_dir/$target_name.optimized.ap_"
2553      }
2554      if (_short_resource_paths) {
2555        _resources_path_map_out_path =
2556            "${target_gen_dir}/${_template_name}_resources_path_map.txt"
2557      }
2558      _optimize_resources_target = "${_template_name}__optimize_resources"
2559      optimize_resources(_optimize_resources_target) {
2560        deps = _non_java_deps + [ ":$_compile_resources_target" ]
2561        short_resource_paths = _short_resource_paths
2562        strip_resource_names = _strip_resource_names
2563        if (_short_resource_paths) {
2564          resources_path_map_out_path = _resources_path_map_out_path
2565        }
2566        r_text_path = _compile_resources_rtxt_out
2567        if (_is_bundle_module) {
2568          proto_input_path = _proto_resources_path
2569          optimized_proto_output = _optimized_proto_resources_path
2570        } else {
2571          arsc_input_path = _arsc_resources_path
2572          optimized_arsc_output = _optimized_arsc_resources_path
2573        }
2574        resources_config_paths = []
2575        if (_strip_unused_resources) {
2576          resources_config_paths += [ _unused_resources_config_path ]
2577          deps += [ ":$_unused_resources_target" ]
2578        }
2579        if (defined(invoker.resources_config_paths)) {
2580          resources_config_paths += invoker.resources_config_paths
2581        }
2582      }
2583
2584      if (_strip_unused_resources) {
2585        # Copy the unused resources config to the final bundle output dir.
2586        _copy_unused_resources_target =
2587            "${_template_name}__copy_unused_resources"
2588        _final_deps += [ ":$_copy_unused_resources_target" ]
2589      }
2590
2591      # Bundles write their pathmap in a android_app_bundle template.
2592      if (_short_resource_paths && !_is_bundle_module) {
2593        _final_resources_pathmap_path = "${_final_apk_path}.pathmap.txt"
2594        _copy_pathmap_target = "${_template_name}__copy_pathmap"
2595        copy(_copy_pathmap_target) {
2596          deps = [ ":$_optimize_resources_target" ]
2597          sources = [ _resources_path_map_out_path ]
2598          outputs = [ _final_resources_pathmap_path ]
2599        }
2600        _final_deps += [ ":$_copy_pathmap_target" ]
2601      }
2602    } else {
2603      not_needed(invoker, [ "resources_config_paths" ])
2604    }
2605
2606    if (!_is_bundle_module) {
2607      # Output the R.txt file to a more easily discoverable location for
2608      # archiving. This is necessary when stripping resource names so that we
2609      # have an archive of resource names to ids for shipped apks (for
2610      # debugging purposes). We copy the file rather than change the location
2611      # of the original because other targets rely on the location of the R.txt
2612      # file.
2613      _copy_rtxt_target = "${_template_name}__copy_rtxt"
2614      copy(_copy_rtxt_target) {
2615        deps = [ ":$_compile_resources_target" ]
2616        sources = [ _compile_resources_rtxt_out ]
2617        outputs = [ _final_rtxt_path ]
2618      }
2619      _final_deps += [ ":$_copy_rtxt_target" ]
2620    }
2621
2622    if (defined(_resource_sizes_arsc_path)) {
2623      _copy_arsc_target = "${_template_name}__copy_arsc"
2624      copy(_copy_arsc_target) {
2625        deps = [ ":$_compile_resources_target" ]
2626
2627        # resource_sizes.py doesn't care if it gets the optimized .arsc.
2628        sources = [ _arsc_resources_path ]
2629        outputs = [ _resource_sizes_arsc_path ]
2630      }
2631      _final_deps += [ ":$_copy_arsc_target" ]
2632    }
2633
2634    if (defined(invoker.generate_native_libraries_java)) {
2635      _generate_native_libraries_java = invoker.generate_native_libraries_java
2636    } else {
2637      _generate_native_libraries_java =
2638          _is_base_module && !_omit_dex && !defined(invoker.apk_under_test)
2639    }
2640    if (_generate_native_libraries_java) {
2641      write_native_libraries_java("${_template_name}__native_libraries") {
2642        # Do not add a dep on the generated_file target in order to avoid having
2643        # to build the native libraries before this target. The dependency is
2644        # instead captured via a depfile.
2645        if (_uses_static_library) {
2646          _prefix = get_label_info(invoker.static_library_provider,
2647                                   "target_gen_dir") + "/" +
2648                    get_label_info(invoker.static_library_provider, "name")
2649          if (defined(invoker.static_library_provider_use_secondary_abi) &&
2650              invoker.static_library_provider_use_secondary_abi) {
2651            native_libraries_list_file = "${_prefix}.secondary_abi_native_libs"
2652            _use_secondary_abi = true
2653          } else {
2654            native_libraries_list_file = "${_prefix}.native_libs"
2655            _use_secondary_abi = false
2656          }
2657        } else if (_native_libs_deps != []) {
2658          native_libraries_list_file = _shared_library_list_file
2659          _use_secondary_abi = false
2660        } else if (_secondary_abi_native_libs_deps != []) {
2661          native_libraries_list_file = _secondary_abi_shared_library_list_file
2662          _use_secondary_abi = true
2663        }
2664
2665        if (defined(_use_secondary_abi)) {
2666          if (_use_secondary_abi || !android_64bit_target_cpu) {
2667            native_lib_32_bit = true
2668          } else {
2669            native_lib_64_bit = true
2670          }
2671        }
2672
2673        enable_chromium_linker = _use_chromium_linker
2674        use_final_fields = true
2675      }
2676      _srcjar_deps += [ ":${_template_name}__native_libraries" ]
2677    }
2678
2679    _loadable_modules = []
2680    if (defined(invoker.loadable_modules)) {
2681      _loadable_modules = invoker.loadable_modules
2682    }
2683    _sanitizer_loadable_modules = []
2684    _sanitizer_deps = []
2685    if (_is_base_module && _native_libs_deps != [] && !_uses_static_library) {
2686      _sanitizer_loadable_modules += _sanitizer_runtimes
2687    }
2688    if (is_asan && _is_base_module &&
2689        (_uses_static_library || _native_libs_deps != [])) {
2690      _sanitizer_loadable_modules +=
2691          [ "$root_gen_dir/build/android/generate_wrap_sh/wrap.sh" ]
2692      _sanitizer_deps += [ "//build/android:generate_wrap_sh" ]
2693    }
2694
2695    _assertions_implicitly_enabled = defined(invoker.custom_assertion_handler)
2696
2697    # Many possible paths where we wouldn't use this variable.
2698    not_needed([ "_assertions_implicitly_enabled" ])
2699
2700    _generate_buildconfig_java = !defined(invoker.apk_under_test) && !_omit_dex
2701    if (defined(invoker.generate_buildconfig_java)) {
2702      _generate_buildconfig_java = invoker.generate_buildconfig_java
2703    }
2704    if (_generate_buildconfig_java) {
2705      generate_build_config_srcjar("${_template_name}__build_config_srcjar") {
2706        forward_variables_from(invoker,
2707                               [
2708                                 "disable_strict_mode_context",
2709                                 "isolated_splits_enabled",
2710                               ])
2711        is_bundle = _is_bundle_module
2712        assertions_implicitly_enabled = _assertions_implicitly_enabled
2713        is_incremental_install = _incremental_apk
2714        version_code = _version_code
2715        min_sdk_version = _min_sdk_version
2716        write_clang_profiling_data =
2717            use_clang_coverage && _generate_native_libraries_java
2718        if (defined(invoker.build_config_include_product_version_resource) &&
2719            invoker.build_config_include_product_version_resource) {
2720          resources_version_variable =
2721              "org.chromium.base.R.string.product_version"
2722        }
2723        if (defined(invoker.suffix_apk_assets_used_by)) {
2724          deps = [ ":$_build_config_target" ]
2725          inputs = [ _build_config ]
2726          apk_assets_suffixed_list =
2727              "@FileArg(${_rebased_build_config}:apk_assets_suffixed_list)"
2728          apk_assets_suffix =
2729              "@FileArg(${_rebased_build_config}:apk_assets_suffix)"
2730        }
2731      }
2732      _srcjar_deps += [ ":${_template_name}__build_config_srcjar" ]
2733    }
2734
2735    if (_generate_productconfig_java) {
2736      foreach(_package, invoker.product_config_java_packages) {
2737        _locale_target_name =
2738            "${_template_name}_${_package}__product_config_srcjar"
2739        generate_product_config_srcjar("$_locale_target_name") {
2740          build_config = _build_config
2741          java_package = _package
2742          use_chromium_linker = _use_chromium_linker
2743          deps = [ ":$_build_config_target" ]
2744        }
2745        _srcjar_deps += [ ":$_locale_target_name" ]
2746      }
2747    }
2748
2749    if (_is_bundle_module) {
2750      _add_view_trace_events =
2751          defined(invoker.add_view_trace_events) &&
2752          invoker.add_view_trace_events && enable_trace_event_bytecode_rewriting
2753    }
2754
2755    # We cannot skip this target when omit_dex = true because it writes the
2756    # build_config.json.
2757    java_library_impl(_java_target_name) {
2758      forward_variables_from(invoker,
2759                             [
2760                               "alternative_android_sdk_dep",
2761                               "android_manifest",
2762                               "android_manifest_dep",
2763                               "annotation_processor_deps",
2764                               "apk_under_test",
2765                               "asset_deps",
2766                               "base_module_target",
2767                               "chromium_code",
2768                               "deps",
2769                               "jacoco_never_instrument",
2770                               "jar_excluded_patterns",
2771                               "javac_args",
2772                               "mergeable_android_manifests",
2773                               "native_lib_placeholders",
2774                               "parent_module_target",
2775                               "processor_args_javac",
2776                               "secondary_abi_loadable_modules",
2777                               "secondary_native_lib_placeholders",
2778                               "sources",
2779                               "suffix_apk_assets_used_by",
2780                               "library_always_compress",
2781                             ])
2782      version_code = _version_code
2783      version_name = _version_name
2784      if (_is_bundle_module) {
2785        type = "android_app_bundle_module"
2786        res_size_info_path = _res_size_info_path
2787        if (defined(invoker.module_name)) {
2788          module_name = invoker.module_name
2789        } else {
2790          module_name = "base"
2791        }
2792        add_view_trace_events = _add_view_trace_events
2793      } else {
2794        type = "android_apk"
2795      }
2796      r_text_path = _compile_resources_rtxt_out
2797      main_target_name = _template_name
2798      supports_android = true
2799      requires_android = true
2800      srcjar_deps = _srcjar_deps
2801      merged_android_manifest = _android_manifest
2802      if (defined(_final_dex_path)) {
2803        final_dex_path = _final_dex_path
2804      }
2805      if (defined(invoker.assert_no_native_deps)) {
2806        assert_no_deps = invoker.assert_no_native_deps
2807      }
2808
2809      if (_is_bundle_module) {
2810        proto_resources_path = _proto_resources_path
2811        if (_optimize_resources) {
2812          proto_resources_path = _optimized_proto_resources_path
2813          if (_short_resource_paths) {
2814            module_pathmap_path = _resources_path_map_out_path
2815          }
2816        }
2817      } else {
2818        apk_path = _final_apk_path
2819        if (_incremental_apk) {
2820          incremental_apk_path = _incremental_apk_path
2821          incremental_install_json_path = _incremental_install_json_path
2822        }
2823      }
2824
2825      proguard_enabled = _proguard_enabled
2826      if (_proguard_enabled) {
2827        proguard_configs = [ _generated_proguard_config ]
2828        if (defined(invoker.proguard_configs)) {
2829          proguard_configs += invoker.proguard_configs
2830        }
2831        if (!_is_bundle_module) {
2832          proguard_mapping_path = _proguard_mapping_path
2833        }
2834      }
2835
2836      # Do not add a dep on the generated_file target in order to avoid having
2837      # to build the native libraries before this target. The dependency is
2838      # instead captured via a depfile.
2839      if (_native_libs_deps != []) {
2840        shared_libraries_runtime_deps_file = _shared_library_list_file
2841      }
2842      if (defined(_secondary_abi_shared_library_list_file)) {
2843        secondary_abi_shared_libraries_runtime_deps_file =
2844            _secondary_abi_shared_library_list_file
2845      }
2846
2847      if (!defined(deps)) {
2848        deps = []
2849      }
2850      deps += _sanitizer_deps
2851      loadable_modules = _loadable_modules + _sanitizer_loadable_modules
2852
2853      if (defined(_allowlist_r_txt_path) && _is_bundle_module) {
2854        # Used to write the file path to the target's .build_config.json only.
2855        base_allowlist_rtxt_path = _allowlist_r_txt_path
2856      }
2857    }
2858
2859    # Old name for variable, mark as not_needed while it is being renamed
2860    # downstream. Remove after all references to baseline_profile_path have been
2861    # changed.
2862    not_needed(invoker, [ "baseline_profile_path" ])
2863
2864    _enable_art_profile_optimizations =
2865        defined(invoker.art_profile_path) && _proguard_enabled
2866
2867    if (_enable_art_profile_optimizations) {
2868      _include_baseline_profile = enable_baseline_profiles
2869      _enable_startup_profile = enable_startup_profiles
2870      if (_include_baseline_profile) {
2871        _obfuscated_art_profile =
2872            "$target_out_dir/${target_name}.obfuscated.hrf"
2873      }
2874    } else {
2875      not_needed(invoker, [ "art_profile_path" ])
2876    }
2877
2878    if (_is_bundle_module || _omit_dex) {
2879      # Dex generation for app bundle modules take place in the
2880      # android_app_bundle template.
2881      not_needed(invoker, [ "custom_assertion_handler" ])
2882    } else if (_incremental_apk) {
2883      not_needed(invoker,
2884                 [
2885                   "enable_proguard_checks",
2886                   "custom_assertion_handler",
2887                 ])
2888    } else {
2889      _final_dex_target_name = "${_template_name}__final_dex"
2890      dex(_final_dex_target_name) {
2891        forward_variables_from(invoker,
2892                               [
2893                                 "enable_proguard_checks",
2894                                 "custom_assertion_handler",
2895                                 "proguard_enable_obfuscation",
2896                                 "repackage_classes",
2897                               ])
2898        min_sdk_version = _min_sdk_version
2899        proguard_enabled = _proguard_enabled
2900        build_config = _build_config
2901        output = _final_dex_path
2902        deps = [
2903          ":$_build_config_target",
2904          ":$_java_target_name",
2905        ]
2906        if (_proguard_enabled) {
2907          # Generates proguard configs
2908          deps += [ ":$_compile_resources_target" ]
2909          proguard_mapping_path = _proguard_mapping_path
2910          has_apk_under_test = defined(invoker.apk_under_test)
2911
2912          if (_enable_art_profile_optimizations) {
2913            input_art_profile = invoker.art_profile_path
2914            if (_include_baseline_profile) {
2915              output_art_profile = _obfuscated_art_profile
2916            }
2917            enable_startup_profile = _enable_startup_profile
2918          }
2919
2920          # Must not be set via write_build_config, because that will cause it
2921          # to be picked up by test apks that use apk_under_test.
2922          if (!_assertions_implicitly_enabled && !enable_java_asserts &&
2923              (!defined(testonly) || !testonly) &&
2924              # Injected JaCoCo code causes -checkdiscards to fail.
2925              !use_jacoco_coverage) {
2926            proguard_configs = [
2927              "//build/android/dcheck_is_off.flags",
2928              "//third_party/jni_zero/checkdiscard_proguard.flags",
2929            ]
2930          }
2931        } else {
2932          if (_min_sdk_version >= default_min_sdk_version) {
2933            # Enable dex merging only when min_sdk_version is >= what the library
2934            # .dex files were created with.
2935            input_dex_filearg =
2936                "@FileArg(${_rebased_build_config}:deps_info:all_dex_files)"
2937
2938            # Pure dex-merge.
2939            enable_desugar = false
2940          } else {
2941            input_classes_filearg =
2942                "@FileArg($_rebased_build_config:deps_info:device_classpath)"
2943          }
2944        }
2945
2946        # The individual dependencies would have caught real missing deps in
2947        # their respective dex steps. False positives that were suppressed at
2948        # per-target dex steps are emitted here since this may use jar files
2949        # rather than dex files.
2950        if (!defined(enable_desugar)) {
2951          ignore_desugar_missing_deps = true
2952        }
2953      }
2954
2955      _final_dex_target_dep = ":$_final_dex_target_name"
2956
2957      if (_enable_art_profile_optimizations && _include_baseline_profile) {
2958        _binary_profile_target = "${_template_name}__binary_baseline_profile"
2959        _binary_baseline_profile_path =
2960            "$target_out_dir/$_template_name.baseline.prof"
2961        _binary_baseline_profile_metadata_path =
2962            _binary_baseline_profile_path + "m"
2963        create_binary_profile(_binary_profile_target) {
2964          forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
2965          binary_baseline_profile_path = _binary_baseline_profile_path
2966          binary_baseline_profile_metadata_path =
2967              _binary_baseline_profile_metadata_path
2968          build_config = _build_config
2969          input_profile_path = _obfuscated_art_profile
2970          deps = [
2971            ":$_build_config_target",
2972            _final_dex_target_dep,
2973          ]
2974        }
2975      }
2976
2977      # Unused resources target for bundles handled in android_app_bundle
2978      # template.
2979      if (_strip_unused_resources && !_is_bundle_module) {
2980        unused_resources(_unused_resources_target) {
2981          deps = [
2982            ":$_build_config_target",
2983            ":$_compile_resources_target",
2984            ":$_final_dex_target_name",
2985          ]
2986          build_config = _build_config
2987          if (_proguard_enabled) {
2988            proguard_mapping_path = _proguard_mapping_path
2989          }
2990          output_config = _unused_resources_config_path
2991        }
2992      }
2993    }
2994
2995    _all_native_libs_deps = _native_libs_deps + _secondary_abi_native_libs_deps
2996    if (_all_native_libs_deps != []) {
2997      _native_libs_filearg_dep = ":$_build_config_target"
2998      _all_native_libs_deps += [ _native_libs_filearg_dep ]
2999
3000      if (!_is_bundle_module) {
3001        _native_libs_filearg =
3002            "@FileArg($_rebased_build_config:native:libraries)"
3003      }
3004    }
3005
3006    if (_is_bundle_module) {
3007      _final_deps += [
3008                       ":$_build_config_target",
3009                       ":$_compile_resources_target",
3010                       ":$_merge_manifest_target",
3011                     ] + _all_native_libs_deps
3012      if (defined(invoker.asset_deps)) {
3013        _final_deps += invoker.asset_deps
3014      }
3015      if (_optimize_resources) {
3016        _final_deps += [ ":$_optimize_resources_target" ]
3017      }
3018      if (defined(_final_dex_target_dep)) {
3019        not_needed([ "_final_dex_target_dep" ])
3020      }
3021    } else {
3022      # Generate size-info/*.jar.info files.
3023      if (defined(invoker.name)) {
3024        # Create size info files for targets that care about size
3025        # (have proguard enabled).
3026        _include_size_info =
3027            defined(invoker.include_size_info) && invoker.include_size_info
3028        if (_include_size_info || _proguard_enabled) {
3029          _size_info_target = "${target_name}__size_info"
3030          create_size_info_files(_size_info_target) {
3031            name = "${invoker.name}.apk"
3032            build_config = _build_config
3033            res_size_info_path = _res_size_info_path
3034            deps = [
3035              ":$_build_config_target",
3036              ":$_compile_resources_target",
3037              ":$_java_target_name",
3038            ]
3039            if (defined(invoker.asset_deps)) {
3040              deps += invoker.asset_deps
3041            }
3042          }
3043          _final_deps += [ ":$_size_info_target" ]
3044        } else {
3045          not_needed(invoker, [ "name" ])
3046        }
3047      }
3048
3049      _create_apk_target = "${_template_name}__create"
3050      _final_deps += [ ":$_create_apk_target" ]
3051      package_apk("$_create_apk_target") {
3052        forward_variables_from(invoker,
3053                               [
3054                                 "expected_libs_and_assets",
3055                                 "expected_libs_and_assets_base",
3056                                 "keystore_name",
3057                                 "keystore_path",
3058                                 "keystore_password",
3059                                 "native_lib_placeholders",
3060                                 "secondary_abi_loadable_modules",
3061                                 "secondary_native_lib_placeholders",
3062                                 "uncompress_dex",
3063                                 "library_always_compress",
3064                               ])
3065
3066        if (defined(expected_libs_and_assets)) {
3067          build_config_dep = ":$_build_config_target"
3068          top_target_name = _template_name
3069        }
3070
3071        build_config = _build_config
3072        min_sdk_version = _min_sdk_version
3073        packaged_resources_path = _arsc_resources_path
3074
3075        # Need full deps rather than _non_java_deps, because loadable_modules
3076        # may include .so files extracted by __unpack_aar targets.
3077        deps = _invoker_deps + _sanitizer_deps + [ ":$_build_config_target" ]
3078        if (defined(invoker.asset_deps)) {
3079          deps += invoker.asset_deps
3080        }
3081
3082        if (_incremental_apk) {
3083          _dex_target = "//build/android/incremental_install:apk_dex"
3084
3085          deps += [
3086            ":$_compile_resources_target",
3087            _dex_target,
3088          ]
3089
3090          dex_path = get_label_info(_dex_target, "target_out_dir") + "/apk.dex"
3091
3092          # Incremental APKs cannot be installed via `adb install` as such they
3093          # should be clearly named/labeled "incremental".
3094          output_apk_path = _incremental_apk_path
3095
3096          loadable_modules = _sanitizer_loadable_modules
3097
3098          # All native libraries are side-loaded, so use a placeholder to force
3099          # the proper bitness for the app.
3100          _has_native_libs =
3101              defined(_native_libs_filearg) || _loadable_modules != [] ||
3102              _sanitizer_loadable_modules != []
3103          if (_has_native_libs && loadable_modules == [] &&
3104              !defined(native_lib_placeholders)) {
3105            native_lib_placeholders = [ "libfix.crbug.384638.so" ]
3106          }
3107        } else {
3108          loadable_modules = _loadable_modules + _sanitizer_loadable_modules
3109          deps += _all_native_libs_deps + [
3110                    ":$_compile_resources_target",
3111                    ":$_merge_manifest_target",
3112                  ]
3113
3114          if (defined(_final_dex_path)) {
3115            dex_path = _final_dex_path
3116            deps += [ _final_dex_target_dep ]
3117            if (_enable_art_profile_optimizations &&
3118                _include_baseline_profile) {
3119              # extra_assets is a list of ["{src_path}:{dst_path}"]
3120              extra_assets = [
3121                rebase_path(_binary_baseline_profile_path, root_build_dir) +
3122                    ":dexopt/baseline.prof",
3123                rebase_path(_binary_baseline_profile_metadata_path,
3124                            root_build_dir) + ":dexopt/baseline.profm",
3125              ]
3126              deps += [ ":$_binary_profile_target" ]
3127            }
3128          }
3129
3130          output_apk_path = _final_apk_path
3131
3132          if (_optimize_resources) {
3133            packaged_resources_path = _optimized_arsc_resources_path
3134            deps += [ ":$_optimize_resources_target" ]
3135          } else {
3136            packaged_resources_path = _arsc_resources_path
3137            deps += [ ":$_compile_resources_target" ]
3138          }
3139
3140          if (defined(_native_libs_filearg)) {
3141            native_libs_filearg = _native_libs_filearg
3142            secondary_abi_native_libs_filearg = "@FileArg($_rebased_build_config:native:secondary_abi_libraries)"
3143          }
3144        }
3145      }
3146    }
3147
3148    if (_incremental_apk) {
3149      _write_installer_json_rule_name = "${_template_name}__incremental_json"
3150      action_with_pydeps(_write_installer_json_rule_name) {
3151        script = "//build/android/incremental_install/write_installer_json.py"
3152        deps = [ ":$_build_config_target" ] + _all_native_libs_deps
3153
3154        data = [ _incremental_install_json_path ]
3155        inputs = [ _build_config ]
3156        outputs = [ _incremental_install_json_path ]
3157
3158        _rebased_incremental_apk_path =
3159            rebase_path(_incremental_apk_path, root_build_dir)
3160        _rebased_incremental_install_json_path =
3161            rebase_path(_incremental_install_json_path, root_build_dir)
3162        args = [
3163          "--apk-path=$_rebased_incremental_apk_path",
3164          "--output-path=$_rebased_incremental_install_json_path",
3165          "--dex-file=@FileArg($_rebased_build_config:deps_info:all_dex_files)",
3166        ]
3167        if (_proguard_enabled) {
3168          args += [ "--show-proguard-warning" ]
3169        }
3170        if (defined(_native_libs_filearg)) {
3171          args += [ "--native-libs=$_native_libs_filearg" ]
3172          deps += [ _native_libs_filearg_dep ]
3173        }
3174        if (_loadable_modules != []) {
3175          _rebased_loadable_modules =
3176              rebase_path(_loadable_modules, root_build_dir)
3177          args += [ "--native-libs=$_rebased_loadable_modules" ]
3178        }
3179      }
3180      _final_deps += [ ":$_write_installer_json_rule_name" ]
3181    }
3182
3183    # Generate apk operation related script.
3184    if (!_is_bundle_module &&
3185        (!defined(invoker.create_apk_script) || invoker.create_apk_script)) {
3186      if (_uses_static_library) {
3187        _install_artifacts_target = "${target_name}__install_artifacts"
3188        _install_artifacts_json =
3189            "${target_gen_dir}/${target_name}.install_artifacts"
3190        generated_file(_install_artifacts_target) {
3191          output_conversion = "json"
3192          deps = [ invoker.static_library_provider ]
3193          outputs = [ _install_artifacts_json ]
3194          data_keys = [ "install_artifacts" ]
3195          rebase = root_build_dir
3196        }
3197      }
3198      _apk_operations_target_name = "${target_name}__apk_operations"
3199      action_with_pydeps(_apk_operations_target_name) {
3200        _generated_script = "$root_build_dir/bin/${invoker.target_name}"
3201        script = "//build/android/gyp/create_apk_operations_script.py"
3202        outputs = [ _generated_script ]
3203        args = [
3204          "--script-output-path",
3205          rebase_path(_generated_script, root_build_dir),
3206          "--target-cpu=$target_cpu",
3207        ]
3208        if (defined(invoker.command_line_flags_file)) {
3209          args += [
3210            "--command-line-flags-file",
3211            invoker.command_line_flags_file,
3212          ]
3213        }
3214        if (_incremental_apk) {
3215          args += [
3216            "--incremental-install-json-path",
3217            rebase_path(_incremental_install_json_path, root_build_dir),
3218          ]
3219        } else {
3220          args += [
3221            "--apk-path",
3222            rebase_path(_final_apk_path, root_build_dir),
3223          ]
3224        }
3225        if (_uses_static_library) {
3226          deps = [ ":$_install_artifacts_target" ]
3227          _rebased_install_artifacts_json =
3228              rebase_path(_install_artifacts_json, root_build_dir)
3229          _static_library_apk_path =
3230              "@FileArg($_rebased_install_artifacts_json[])"
3231          args += [
3232            "--additional-apk",
3233            _static_library_apk_path,
3234          ]
3235        }
3236        data = []
3237        data_deps = [
3238          "//build/android:apk_operations_py",
3239          "//build/android:stack_tools",
3240        ]
3241
3242        if (_proguard_enabled && !_incremental_apk) {
3243          # Required by logcat command.
3244          data_deps += [ "//build/android/stacktrace:java_deobfuscate" ]
3245          data += [ "$_final_apk_path.mapping" ]
3246          args += [
3247            "--proguard-mapping-path",
3248            rebase_path("$_final_apk_path.mapping", root_build_dir),
3249          ]
3250        }
3251      }
3252      _final_deps += [ ":$_apk_operations_target_name" ]
3253    }
3254
3255    _enable_lint = defined(invoker.enable_lint) && invoker.enable_lint &&
3256                   !disable_android_lint
3257    if (_enable_lint) {
3258      android_lint("${target_name}__lint") {
3259        forward_variables_from(invoker,
3260                               [
3261                                 "lint_baseline_file",
3262                                 "lint_gen_dir",
3263                                 "lint_suppressions_file",
3264                                 "min_sdk_version",
3265                               ])
3266        build_config = _build_config
3267        build_config_dep = ":$_build_config_target"
3268
3269        # This will use library subtargets under-the-hood
3270        deps = [ ":$_java_target_name" ]
3271        if (defined(invoker.lint_suppressions_dep)) {
3272          deps += [ invoker.lint_suppressions_dep ]
3273        }
3274        if (defined(invoker.asset_deps)) {
3275          deps += invoker.asset_deps
3276        }
3277        if (defined(invoker.lint_min_sdk_version)) {
3278          min_sdk_version = invoker.lint_min_sdk_version
3279        }
3280      }
3281    } else {
3282      not_needed(invoker,
3283                 [
3284                   "lint_baseline_file",
3285                   "lint_gen_dir",
3286                   "lint_jar_path",
3287                   "lint_min_sdk_version",
3288                   "lint_suppressions_dep",
3289                   "lint_suppressions_file",
3290                 ])
3291    }
3292
3293    group(target_name) {
3294      forward_variables_from(invoker,
3295                             [
3296                               "assert_no_deps",
3297                               "data",
3298                               "data_deps",
3299                             ])
3300      metadata = {
3301        if (defined(invoker.metadata)) {
3302          forward_variables_from(invoker.metadata, "*")
3303        }
3304
3305        # Allows metadata collection via apk targets that traverse only java deps.
3306        java_walk_keys = [ ":$_java_target_name" ]
3307      }
3308
3309      # Generate apk related operations at runtime.
3310      public_deps = _final_deps
3311
3312      if (!defined(data_deps)) {
3313        data_deps = []
3314      }
3315
3316      # Include unstripped native libraries so tests can symbolize stacks.
3317      data_deps += _all_native_libs_deps + [ ":${_java_target_name}__validate" ]
3318      if (_enable_lint) {
3319        data_deps += [ ":${target_name}__lint" ]
3320      }
3321
3322      if (_uses_static_library) {
3323        data_deps += [ invoker.static_library_provider ]
3324      }
3325    }
3326  }
3327
3328  # Declare an Android APK target
3329  #
3330  # This target creates an Android APK containing java code, resources, assets,
3331  # and (possibly) native libraries.
3332  #
3333  # Supports all variables of android_apk_or_module(), plus:
3334  #   apk_name: Name for final apk.
3335  #   final_apk_path: (Optional) path to output APK.
3336  #
3337  # Example
3338  #   android_apk("foo_apk") {
3339  #     android_manifest = "AndroidManifest.xml"
3340  #     sources = [
3341  #       "android/org/chromium/foo/FooApplication.java",
3342  #       "android/org/chromium/foo/FooActivity.java",
3343  #     ]
3344  #     deps = [
3345  #       ":foo_support_java"
3346  #       ":foo_resources"
3347  #     ]
3348  #     srcjar_deps = [
3349  #       ":foo_generated_enum"
3350  #     ]
3351  #     shared_libraries = [
3352  #       ":my_shared_lib",
3353  #     ]
3354  #   }
3355  template("android_apk") {
3356    # TODO(crbug.com/40114668): Remove.
3357    not_needed(invoker, [ "no_build_hooks" ])
3358    android_apk_or_module(target_name) {
3359      forward_variables_from(
3360          invoker,
3361          [
3362            "aapt_locale_allowlist",
3363            "additional_jar_files",
3364            "allow_unused_jni_from_native",
3365            "alternative_android_sdk_dep",
3366            "android_manifest",
3367            "android_manifest_dep",
3368            "annotation_processor_deps",
3369            "apk_under_test",
3370            "app_as_shared_lib",
3371            "art_profile_path",
3372            "assert_no_deps",
3373            "assert_no_native_deps",
3374            "asset_deps",
3375            "baseline_profile_path",
3376            "build_config_include_product_version_resource",
3377            "bundles_supported",
3378            "chromium_code",
3379            "command_line_flags_file",
3380            "create_apk_script",
3381            "custom_assertion_handler",
3382            "data",
3383            "data_deps",
3384            "deps",
3385            "enable_lint",
3386            "enable_proguard_checks",
3387            "disable_strict_mode_context",
3388            "enforce_resource_overlays_in_tests",
3389            "expected_android_manifest",
3390            "expected_android_manifest_base",
3391            "expected_android_manifest_library_version_offset",
3392            "expected_android_manifest_version_code_offset",
3393            "expected_libs_and_assets",
3394            "expected_libs_and_assets_base",
3395            "generate_buildconfig_java",
3396            "generate_native_libraries_java",
3397            "include_size_info",
3398            "input_jars_paths",
3399            "jacoco_never_instrument",
3400            "javac_args",
3401            "keystore_name",
3402            "keystore_password",
3403            "keystore_path",
3404            "lint_baseline_file",
3405            "lint_gen_dir",
3406            "lint_min_sdk_version",
3407            "lint_suppressions_dep",
3408            "lint_suppressions_file",
3409            "loadable_modules",
3410            "manifest_package",
3411            "max_sdk_version",
3412            "mergeable_android_manifests",
3413            "product_config_java_packages",
3414            "min_sdk_version",
3415            "native_lib_placeholders",
3416            "never_incremental",
3417            "omit_dex",
3418            "png_to_webp",
3419            "post_process_package_resources_script",
3420            "processor_args_javac",
3421            "proguard_configs",
3422            "proguard_enabled",
3423            "proguard_enable_obfuscation",
3424            "r_java_root_package_name",
3425            "repackage_classes",
3426            "resource_exclusion_exceptions",
3427            "resource_exclusion_regex",
3428            "resource_ids_provider_dep",
3429            "resource_values_filter_rules",
3430            "resources_config_paths",
3431            "require_native_mocks",
3432            "secondary_abi_loadable_modules",
3433            "secondary_abi_shared_libraries",
3434            "secondary_native_lib_placeholders",
3435            "shared_libraries",
3436            "shared_resources",
3437            "shared_resources_allowlist_locales",
3438            "shared_resources_allowlist_target",
3439            "short_resource_paths",
3440            "sources",
3441            "srcjar_deps",
3442            "static_library_provider",
3443            "static_library_provider_use_secondary_abi",
3444            "strip_unused_resources",
3445            "strip_resource_names",
3446            "suffix_apk_assets_used_by",
3447            "target_sdk_version",
3448            "testonly",
3449            "uncompress_dex",
3450            "library_always_compress",
3451            "use_chromium_linker",
3452            "version_code",
3453            "version_name",
3454            "visibility",
3455          ])
3456      is_bundle_module = false
3457      name = invoker.apk_name
3458      if (defined(invoker.final_apk_path)) {
3459        final_apk_path = invoker.final_apk_path
3460      } else {
3461        final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk"
3462      }
3463      metadata = {
3464        install_artifacts = [ final_apk_path ]
3465        if (defined(invoker.static_library_provider)) {
3466          install_artifacts_barrier = []
3467        }
3468      }
3469
3470      # TODO(smaier) - there were some remaining usages of this in angle. Once
3471      # they are removed, remove this line.
3472      not_needed(invoker, [ "generate_final_jni" ])
3473    }
3474  }
3475
3476  # Declare an Android app bundle module target.
3477  #
3478  # The module can be used for an android_apk_or_module().
3479  #
3480  # Supports all variables of android_library(), plus:
3481  #   module_name: Name of the module.
3482  #   is_base_module: If defined and true, indicates that this is the bundle's
3483  #     base module (optional).
3484  #   base_module_target: Base module target of the bundle this module will be
3485  #     added to (optional). Can only be specified for non-base modules.
3486  template("android_app_bundle_module") {
3487    _is_base_module = defined(invoker.is_base_module) && invoker.is_base_module
3488
3489    if (_is_base_module) {
3490      assert(!defined(invoker.base_module_target))
3491    } else {
3492      assert(!defined(invoker.app_as_shared_lib))
3493      assert(!defined(invoker.shared_resources))
3494      assert(!defined(invoker.shared_resources_allowlist_target))
3495      assert(!defined(invoker.shared_resources_allowlist_locales))
3496      assert(defined(invoker.base_module_target))
3497    }
3498
3499    # android_app_bundle's write_build_config expects module targets to be named
3500    # according to java_target_patterns otherwise it ignores them when listed in
3501    # possible_config_deps. See https://crbug.com/1418398.
3502    if (filter_exclude([ target_name ], [ "*_bundle_module" ]) != []) {
3503      assert(false,
3504             "Invalid android_app_bundle_module target name ($target_name), " +
3505                 "must end in _bundle_module.")
3506    }
3507
3508    # TODO(tiborg): We have several flags that are necessary for workarounds
3509    # that come from the fact that the resources get compiled in the bundle
3510    # module target, but bundle modules have to have certain flags in
3511    # common or bundle modules have to know information about the base module.
3512    # Those flags include version_code, version_name, and base_module_target.
3513    # It would be better to move the resource compile target into the bundle
3514    # target. Doing so would keep the bundle modules independent from the bundle
3515    # and potentially reuse the same bundle modules for multiple bundles.
3516    android_apk_or_module(target_name) {
3517      forward_variables_from(
3518          invoker,
3519          [
3520            "add_view_trace_events",
3521            "aapt_locale_allowlist",
3522            "additional_jar_files",
3523            "allow_unused_jni_from_native",
3524            "alternative_android_sdk_dep",
3525            "android_manifest",
3526            "android_manifest_dep",
3527            "annotation_processor_deps",
3528            "app_as_shared_lib",
3529            "assert_no_deps",
3530            "assert_no_native_deps",
3531            "asset_deps",
3532            "base_module_target",
3533            "build_config_include_product_version_resource",
3534            "bundle_target",
3535            "chromium_code",
3536            "custom_assertion_handler",
3537            "data",
3538            "data_deps",
3539            "deps",
3540            "disable_strict_mode_context",
3541            "expected_android_manifest",
3542            "expected_android_manifest_base",
3543            "expected_android_manifest_library_version_offset",
3544            "expected_android_manifest_version_code_offset",
3545            "generate_buildconfig_java",
3546            "generate_native_libraries_java",
3547            "input_jars_paths",
3548            "isolated_splits_enabled",
3549            "is_base_module",
3550            "jacoco_never_instrument",
3551            "jar_excluded_patterns",
3552            "javac_args",
3553            "loadable_modules",
3554            "product_config_java_packages",
3555            "manifest_package",
3556            "max_sdk_version",
3557            "min_sdk_version",
3558            "mergeable_android_manifests",
3559            "override_target_sdk",
3560            "module_name",
3561            "native_lib_placeholders",
3562            "package_id",
3563            "parent_module_target",
3564            "png_to_webp",
3565            "processor_args_javac",
3566            "proguard_configs",
3567            "proguard_enabled",
3568            "proguard_enable_obfuscation",
3569            "repackage_classes",
3570            "resource_exclusion_exceptions",
3571            "resource_exclusion_regex",
3572            "resource_ids_provider_dep",
3573            "resource_values_filter_rules",
3574            "resources_config_paths",
3575            "secondary_abi_loadable_modules",
3576            "secondary_abi_shared_libraries",
3577            "secondary_native_lib_placeholders",
3578            "shared_libraries",
3579            "shared_resources",
3580            "shared_resources_allowlist_locales",
3581            "shared_resources_allowlist_target",
3582            "short_resource_paths",
3583            "srcjar_deps",
3584            "static_library_provider",
3585            "static_library_provider_use_secondary_abi",
3586            "strip_resource_names",
3587            "strip_unused_resources",
3588            "suffix_apk_assets_used_by",
3589            "target_sdk_version",
3590            "testonly",
3591            "library_always_compress",
3592            "use_chromium_linker",
3593            "uses_split",
3594            "version_code",
3595            "version_name",
3596            "visibility",
3597          ])
3598      is_bundle_module = true
3599      generate_buildconfig_java = _is_base_module
3600      if (defined(uses_split)) {
3601        assert(defined(parent_module_target),
3602               "Must set parent_module_target when uses_split is set")
3603      }
3604    }
3605  }
3606
3607  # Declare an Android instrumentation test runner.
3608  #
3609  # This target creates a wrapper script to run Android instrumentation tests.
3610  #
3611  # Arguments:
3612  #   android_test_apk: The target containing the tests.
3613  #
3614  #   The following args are optional:
3615  #   apk_under_test: The target being tested.
3616  #   additional_apks: Additional targets to install on device.
3617  #   data: List of runtime data file dependencies.
3618  #   data_deps: List of non-linked dependencies.
3619  #   deps: List of private dependencies.
3620  #   extra_args: Extra arguments set for test runner.
3621  #   ignore_all_data_deps: Don't build data_deps and additional_apks.
3622  #   modules: Extra dynamic feature modules to install for test target. Can
3623  #     only be used if |apk_under_test| is an Android app bundle.
3624  #   fake_modules: Similar to |modules| but fake installed instead.
3625  #   never_incremental: Disable incremental builds.
3626  #   proguard_enabled: Enable proguard
3627  #   public_deps: List of public dependencies
3628  #
3629  # Example
3630  #   instrumentation_test_runner("foo_test_for_bar") {
3631  #     android_test_apk: ":foo"
3632  #     apk_under_test: ":bar"
3633  #   }
3634  template("instrumentation_test_runner") {
3635    if (use_rts) {
3636      action("${invoker.target_name}__rts_filters") {
3637        script = "//build/add_rts_filters.py"
3638        rts_file = "${root_build_dir}/gen/rts/${invoker.target_name}.filter"
3639        args = [ rebase_path(rts_file, root_build_dir) ]
3640        outputs = [ rts_file ]
3641      }
3642    }
3643    _incremental_apk = !(defined(invoker.never_incremental) &&
3644                         invoker.never_incremental) && incremental_install
3645    _apk_operations_target_name = "${target_name}__apk_operations"
3646    _apk_target = invoker.android_test_apk
3647    if (defined(invoker.apk_under_test) && !_incremental_apk) {
3648      # The actual target is defined in the test_runner_script template.
3649      _install_artifacts_json =
3650          "${target_gen_dir}/${target_name}.install_artifacts"
3651      _install_artifacts_target_name = "${target_name}__install_artifacts"
3652    }
3653
3654    action_with_pydeps(_apk_operations_target_name) {
3655      testonly = true
3656      script = "//build/android/gyp/create_test_apk_wrapper_script.py"
3657      deps = []
3658      _generated_script = "$root_build_dir/bin/${invoker.target_name}"
3659      outputs = [ _generated_script ]
3660      _apk_build_config =
3661          get_label_info(_apk_target, "target_gen_dir") + "/" +
3662          get_label_info(_apk_target, "name") + ".build_config.json"
3663      _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir)
3664      args = [
3665        "--script-output-path",
3666        rebase_path(_generated_script, root_build_dir),
3667        "--package-name",
3668        "@FileArg($_rebased_apk_build_config:deps_info:package_name)",
3669      ]
3670      deps += [ "${_apk_target}$build_config_target_suffix" ]
3671      if (_incremental_apk) {
3672        args += [
3673          "--test-apk-incremental-install-json",
3674          "@FileArg($_rebased_apk_build_config:deps_info:incremental_install_json_path)",
3675        ]
3676      } else {
3677        args += [
3678          "--test-apk",
3679          "@FileArg($_rebased_apk_build_config:deps_info:apk_path)",
3680        ]
3681      }
3682      if (defined(invoker.proguard_mapping_path) && !_incremental_apk) {
3683        args += [
3684          "--proguard-mapping-path",
3685          rebase_path(invoker.proguard_mapping_path, root_build_dir),
3686        ]
3687      }
3688      if (defined(invoker.apk_under_test)) {
3689        if (_incremental_apk) {
3690          deps += [ "${invoker.apk_under_test}$build_config_target_suffix" ]
3691          _apk_under_test_build_config =
3692              get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" +
3693              get_label_info(invoker.apk_under_test, "name") +
3694              ".build_config.json"
3695          _rebased_apk_under_test_build_config =
3696              rebase_path(_apk_under_test_build_config, root_build_dir)
3697          _apk_under_test = "@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path)"
3698        } else {
3699          deps += [ ":${_install_artifacts_target_name}" ]
3700          _rebased_install_artifacts_json =
3701              rebase_path(_install_artifacts_json, root_build_dir)
3702          _apk_under_test = "@FileArg($_rebased_install_artifacts_json[])"
3703        }
3704        args += [
3705          "--additional-apk",
3706          _apk_under_test,
3707        ]
3708      }
3709      if (defined(invoker.additional_apks)) {
3710        foreach(additional_apk, invoker.additional_apks) {
3711          deps += [ "$additional_apk$build_config_target_suffix" ]
3712          _build_config =
3713              get_label_info(additional_apk, "target_gen_dir") + "/" +
3714              get_label_info(additional_apk, "name") + ".build_config.json"
3715          _rebased_build_config = rebase_path(_build_config, root_build_dir)
3716          args += [
3717            "--additional-apk",
3718            "@FileArg($_rebased_build_config:deps_info:apk_path)",
3719          ]
3720        }
3721        deps += invoker.additional_apks
3722      }
3723    }
3724    test_runner_script(target_name) {
3725      forward_variables_from(invoker,
3726                             [
3727                               "additional_apks",
3728                               "additional_locales",
3729                               "apk_under_test",
3730                               "data",
3731                               "data_deps",
3732                               "deps",
3733                               "extra_args",
3734                               "fake_modules",
3735                               "ignore_all_data_deps",
3736                               "is_unit_test",
3737                               "modules",
3738                               "proguard_mapping_path",
3739                               "use_webview_provider",
3740                             ])
3741      test_name = invoker.target_name
3742      test_type = "instrumentation"
3743      apk_target = invoker.android_test_apk
3744      incremental_apk = _incremental_apk
3745
3746      public_deps = [
3747        ":$_apk_operations_target_name",
3748        apk_target,
3749      ]
3750      if (defined(invoker.apk_under_test)) {
3751        public_deps += [ invoker.apk_under_test ]
3752      }
3753      if (defined(invoker.additional_apks)) {
3754        public_deps += invoker.additional_apks
3755      }
3756      if (use_rts) {
3757        if (!defined(data_deps)) {
3758          data_deps = []
3759        }
3760        data_deps += [ ":${invoker.target_name}__rts_filters" ]
3761      }
3762    }
3763  }
3764
3765  # Declare an Android instrumentation test apk
3766  #
3767  # This target creates an Android instrumentation test apk.
3768  #
3769  # Supports all variables of android_apk(), plus:
3770  #   apk_under_test: The apk being tested (optional).
3771  #
3772  # Example
3773  #   android_test_apk("foo_test_apk") {
3774  #     android_manifest = "AndroidManifest.xml"
3775  #     apk_name = "FooTest"
3776  #     apk_under_test = "Foo"
3777  #     sources = [
3778  #       "android/org/chromium/foo/FooTestCase.java",
3779  #       "android/org/chromium/foo/FooExampleTest.java",
3780  #     ]
3781  #     deps = [
3782  #       ":foo_test_support_java"
3783  #     ]
3784  #   }
3785  template("android_test_apk") {
3786    android_apk(target_name) {
3787      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
3788      testonly = true
3789      _use_default_launcher =
3790          !defined(invoker.use_default_launcher) || invoker.use_default_launcher
3791
3792      # The size info enables the test_runner to find the source file location
3793      # of a test after it is ran.
3794      include_size_info = true
3795      data = [ "$root_build_dir/size-info/${invoker.apk_name}.apk.jar.info" ]
3796      if (defined(invoker.data)) {
3797        data += invoker.data
3798      }
3799
3800      if (_use_default_launcher) {
3801        deps = [ "//testing/android/instrumentation:test_runner_java" ]
3802      } else {
3803        deps = []
3804      }
3805      if (defined(invoker.deps)) {
3806        deps += invoker.deps
3807      }
3808      data_deps = [
3809        # Ensure unstripped libraries are included in runtime deps so that
3810        # symbolization can be done.
3811        ":${target_name}__secondary_abi_shared_library_list",
3812        ":${target_name}__shared_library_list",
3813      ]
3814      if (defined(invoker.data_deps)) {
3815        data_deps += invoker.data_deps
3816      }
3817      if (defined(invoker.apk_under_test)) {
3818        data_deps += [ invoker.apk_under_test ]
3819      }
3820
3821      if (defined(invoker.apk_under_test)) {
3822        _under_test_label =
3823            get_label_info(invoker.apk_under_test, "label_no_toolchain")
3824        data_deps += [
3825          "${_under_test_label}__secondary_abi_shared_library_list",
3826          "${_under_test_label}__shared_library_list",
3827        ]
3828      }
3829
3830      if (defined(invoker.additional_apks)) {
3831        data_deps += invoker.additional_apks
3832      }
3833      if (defined(invoker.use_webview_provider)) {
3834        data_deps += [ invoker.use_webview_provider ]
3835      }
3836
3837      if (defined(invoker.proguard_enabled) && invoker.proguard_enabled &&
3838          !incremental_install) {
3839        # When ProGuard is on, we use ProGuard to combine the under test java
3840        # code and the test java code. This is to allow us to apply all ProGuard
3841        # optimizations that we ship with, but not have them break tests. The
3842        # apk under test will still have the same resources, assets, and
3843        # manifest, all of which are the ones used in the tests.
3844        proguard_configs = [
3845          "//testing/android/proguard_for_test.flags",
3846          "//third_party/jni_zero/proguard_for_test.flags",
3847        ]
3848        if (defined(invoker.proguard_configs)) {
3849          proguard_configs += invoker.proguard_configs
3850        }
3851        enable_proguard_checks = false
3852        if (defined(invoker.final_apk_path)) {
3853          _final_apk_path = invoker.final_apk_path
3854        } else {
3855          _final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk"
3856        }
3857        data += [ "$_final_apk_path.mapping" ]
3858      }
3859
3860      create_apk_script = false
3861
3862      forward_variables_from(invoker,
3863                             "*",
3864                             TESTONLY_AND_VISIBILITY + [
3865                                   "data",
3866                                   "data_deps",
3867                                   "deps",
3868                                   "extra_args",
3869                                   "is_unit_test",
3870                                   "proguard_configs",
3871                                 ])
3872    }
3873  }
3874
3875  # Declare an Android instrumentation test apk with wrapper script.
3876  #
3877  # This target creates an Android instrumentation test apk with wrapper script
3878  # to run the test.
3879  #
3880  # Supports all variables of android_test_apk.
3881  template("instrumentation_test_apk") {
3882    assert(defined(invoker.apk_name))
3883    _apk_target_name = "${target_name}__test_apk"
3884    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
3885    android_test_apk(_apk_target_name) {
3886      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
3887    }
3888    instrumentation_test_runner(target_name) {
3889      forward_variables_from(invoker,
3890                             [
3891                               "additional_apks",
3892                               "apk_under_test",
3893                               "data",
3894                               "data_deps",
3895                               "deps",
3896                               "extra_args",
3897                               "ignore_all_data_deps",
3898                               "is_unit_test",
3899                               "modules",
3900                               "never_incremental",
3901                               "public_deps",
3902                               "use_webview_provider",
3903                             ])
3904      android_test_apk = ":${_apk_target_name}"
3905      if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) {
3906        proguard_mapping_path =
3907            "$root_build_dir/apks/${invoker.apk_name}.apk.mapping"
3908      }
3909    }
3910  }
3911
3912  # Declare an Android gtest apk
3913  #
3914  # This target creates an Android apk for running gtest-based unittests.
3915  #
3916  # Variables
3917  #   deps: Specifies the dependencies of this target. These will be passed to
3918  #     the underlying android_apk invocation and should include the java and
3919  #     resource dependencies of the apk.
3920  #   shared_library: shared_library target that contains the unit tests.
3921  #   apk_name: The name of the produced apk. If unspecified, it uses the name
3922  #             of the shared_library target suffixed with "_apk".
3923  #   use_default_launcher: Whether the default activity (NativeUnitTestActivity)
3924  #     should be used for launching tests.
3925  #   allow_cleartext_traffic: (Optional) Whether to allow cleartext network
3926  #     requests during the test.
3927  #   use_native_activity: Test implements ANativeActivity_onCreate().
3928  #
3929  # Example
3930  #   unittest_apk("foo_unittests_apk") {
3931  #     deps = [ ":foo_java", ":foo_resources" ]
3932  #     shared_library = ":foo_unittests"
3933  #   }
3934  template("unittest_apk") {
3935    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
3936    _use_native_activity =
3937        defined(invoker.use_native_activity) && invoker.use_native_activity
3938    _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml"
3939    assert(invoker.shared_library != "")
3940
3941    # This trivial assert is needed in case android_manifest is defined,
3942    # as otherwise _use_native_activity and _android_manifest would not be used.
3943    assert(_use_native_activity != "" && _android_manifest != "")
3944
3945    if (!defined(invoker.android_manifest)) {
3946      _allow_cleartext_traffic = defined(invoker.allow_cleartext_traffic) &&
3947                                 invoker.allow_cleartext_traffic
3948      jinja_template("${target_name}_manifest") {
3949        _native_library_name = get_label_info(invoker.shared_library, "name")
3950        if (defined(invoker.android_manifest_template)) {
3951          input = invoker.android_manifest_template
3952        } else {
3953          input =
3954              "//testing/android/native_test/java/AndroidManifest.xml.jinja2"
3955        }
3956        output = _android_manifest
3957        variables = [
3958          "is_component_build=${is_component_build}",
3959          "native_library_name=${_native_library_name}",
3960          "use_native_activity=${_use_native_activity}",
3961          "allow_cleartext_traffic=${_allow_cleartext_traffic}",
3962        ]
3963      }
3964    }
3965
3966    android_test_apk(target_name) {
3967      data_deps = []
3968      forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
3969      create_apk_script = false
3970
3971      if (!defined(apk_name)) {
3972        apk_name = get_label_info(invoker.shared_library, "name")
3973      }
3974
3975      if (!defined(android_manifest)) {
3976        android_manifest_dep = ":${target_name}_manifest"
3977        android_manifest = _android_manifest
3978      }
3979
3980      final_apk_path = "$root_build_dir/${apk_name}_apk/${apk_name}-debug.apk"
3981
3982      if (!defined(use_default_launcher) || use_default_launcher) {
3983        deps += [
3984          "//build/android/gtest_apk:native_test_instrumentation_test_runner_java",
3985          "//testing/android/native_test:native_test_java",
3986        ]
3987      }
3988      shared_libraries = [ invoker.shared_library ]
3989      deps += [
3990        ":${target_name}__secondary_abi_shared_library_list",
3991        ":${target_name}__shared_library_list",
3992      ]
3993    }
3994  }
3995
3996  # Generate .java files from .aidl files.
3997  #
3998  # This target will store the .java files in a srcjar and should be included in
3999  # an android_library or android_apk's srcjar_deps.
4000  #
4001  # Variables
4002  #   sources: Paths to .aidl files to compile.
4003  #   import_include: Path to directory containing .java files imported by the
4004  #     .aidl files.
4005  #   interface_file: Preprocessed aidl file to import.
4006  #
4007  # Example
4008  #   android_aidl("foo_aidl") {
4009  #     import_include = "java/src"
4010  #     sources = [
4011  #       "java/src/com/foo/bar/FooBarService.aidl",
4012  #       "java/src/com/foo/bar/FooBarServiceCallback.aidl",
4013  #     ]
4014  #   }
4015  template("android_aidl") {
4016    action_with_pydeps(target_name) {
4017      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4018
4019      script = "//build/android/gyp/aidl.py"
4020      depfile = "$target_gen_dir/$target_name.d"
4021      sources = invoker.sources
4022
4023      _srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
4024      _aidl_path = "${android_sdk_build_tools}/aidl"
4025      _framework_aidl = "$android_sdk/framework.aidl"
4026      _imports = [ _framework_aidl ]
4027      if (defined(invoker.interface_file)) {
4028        assert(invoker.interface_file != "")
4029        _imports += [ invoker.interface_file ]
4030      }
4031
4032      inputs = [ _aidl_path ] + _imports
4033
4034      outputs = [ _srcjar_path ]
4035      _rebased_imports = rebase_path(_imports, root_build_dir)
4036      args = [
4037        "--aidl-path",
4038        rebase_path(_aidl_path, root_build_dir),
4039        "--imports=$_rebased_imports",
4040        "--srcjar",
4041        rebase_path(_srcjar_path, root_build_dir),
4042        "--depfile",
4043        rebase_path(depfile, root_build_dir),
4044      ]
4045      if (defined(invoker.import_include) && invoker.import_include != []) {
4046        _rebased_import_paths = []
4047        foreach(_import_path, invoker.import_include) {
4048          _rebased_import_path = []
4049          _rebased_import_path = [ rebase_path(_import_path, root_build_dir) ]
4050          _rebased_import_paths += _rebased_import_path
4051        }
4052        args += [ "--includes=$_rebased_import_paths" ]
4053      }
4054      args += rebase_path(sources, root_build_dir)
4055    }
4056  }
4057
4058  # Compile a protocol buffer to java.
4059  #
4060  # This generates java files from protocol buffers and creates an Android library
4061  # containing the classes.
4062  #
4063  # Variables
4064  #   sources (required)
4065  #       Paths to .proto files to compile.
4066  #
4067  #   proto_path (required)
4068  #       Root directory of .proto files.
4069  #
4070  #   deps (optional)
4071  #       Additional dependencies. Passed through to both the action and the
4072  #       android_library targets.
4073  #
4074  #   import_dirs (optional)
4075  #       A list of extra import directories to be passed to protoc compiler.
4076  #       WARNING: This circumvents proto checkdeps, and should only be used
4077  #       when needed, typically when proto files cannot cleanly import through
4078  #       absolute paths, such as for third_party or generated .proto files.
4079  #       http://crbug.com/691451 tracks fixing this.
4080  #
4081  #   generator_plugin_label (optional)
4082  #       GN label for plugin executable which generates custom cc stubs.
4083  #       Don't specify a toolchain, host toolchain is assumed.
4084  #
4085  # Example:
4086  #  proto_java_library("foo_proto_java") {
4087  #    proto_path = "src/foo"
4088  #    sources = [ "$proto_path/foo.proto" ]
4089  #  }
4090  template("proto_java_library") {
4091    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4092
4093    _template_name = target_name
4094
4095    action_with_pydeps("${_template_name}__protoc_java") {
4096      # The suffix "__protoc_java.srcjar" is used by SuperSize to identify
4097      # protobuf symbols.
4098      _srcjar_path = "$target_gen_dir/$target_name.srcjar"
4099      script = "//build/protoc_java.py"
4100
4101      if (defined(invoker.deps)) {
4102        # Need to care only about targets that might generate .proto files.
4103        # No need to depend on java_library or android_resource targets.
4104        deps = filter_exclude(invoker.deps, java_target_patterns)
4105      }
4106
4107      sources = invoker.sources
4108      depfile = "$target_gen_dir/$target_name.d"
4109      outputs = [ _srcjar_path ]
4110      inputs = [ android_protoc_bin ]
4111      args = [
4112        "--depfile",
4113        rebase_path(depfile, root_build_dir),
4114        "--protoc",
4115        rebase_path(android_protoc_bin, root_build_dir),
4116        "--proto-path",
4117        rebase_path(invoker.proto_path, root_build_dir),
4118        "--srcjar",
4119        rebase_path(_srcjar_path, root_build_dir),
4120      ]
4121
4122      if (defined(invoker.generator_plugin_label)) {
4123        if (host_os == "win") {
4124          _host_executable_suffix = ".exe"
4125        } else {
4126          _host_executable_suffix = ""
4127        }
4128
4129        _plugin_host_label =
4130            invoker.generator_plugin_label + "($host_toolchain)"
4131        _plugin_path =
4132            get_label_info(_plugin_host_label, "root_out_dir") + "/" +
4133            get_label_info(_plugin_host_label, "name") + _host_executable_suffix
4134        args += [
4135          "--plugin",
4136          rebase_path(_plugin_path, root_build_dir),
4137        ]
4138        deps += [ _plugin_host_label ]
4139        inputs += [ _plugin_path ]
4140      }
4141
4142      args += rebase_path(sources, root_build_dir)
4143
4144      if (defined(invoker.import_dirs)) {
4145        foreach(_import_dir, invoker.import_dirs) {
4146          args += [
4147            "--import-dir",
4148            rebase_path(_import_dir, root_build_dir),
4149          ]
4150        }
4151      }
4152    }
4153
4154    android_library(target_name) {
4155      chromium_code = false
4156      sources = []
4157      srcjar_deps = [ ":${_template_name}__protoc_java" ]
4158      deps = [ "//third_party/android_deps:protobuf_lite_runtime_java" ]
4159      if (defined(invoker.deps)) {
4160        deps += invoker.deps
4161      }
4162    }
4163  }
4164
4165  # Compile a flatbuffer to java.
4166  #
4167  # This generates java files from flat buffers and creates an Android library
4168  # containing the classes.
4169  #
4170  # Variables
4171  #   sources (required)
4172  #       Paths to .fbs files to compile.
4173  #
4174  #   root_dir (required)
4175  #       Root directory of .fbs files.
4176  #
4177  #   deps (optional)
4178  #       Additional dependencies. Passed through to both the action and the
4179  #       android_library targets.
4180  #
4181  #   flatc_include_dirs (optional)
4182  #       A list of extra import directories to be passed to flatc compiler.
4183  #
4184  #
4185  # Example:
4186  #  flatbuffer_java_library("foo_flatbuffer_java") {
4187  #    root_dir = "src/foo"
4188  #    sources = [ "$proto_path/foo.fbs" ]
4189  #  }
4190  template("flatbuffer_java_library") {
4191    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4192
4193    _template_name = target_name
4194    _flatc_dep = "//third_party/flatbuffers:flatc($host_toolchain)"
4195    _flatc_out_dir = get_label_info(_flatc_dep, "root_out_dir")
4196    _flatc_bin = "$_flatc_out_dir/flatc"
4197
4198    action_with_pydeps("${_template_name}__flatc_java") {
4199      _srcjar_path = "$target_gen_dir/$target_name.srcjar"
4200      script = "//build/android/gyp/flatc_java.py"
4201
4202      deps = [ _flatc_dep ]
4203      if (defined(invoker.deps)) {
4204        deps += invoker.deps
4205      }
4206      inputs = [ _flatc_bin ]
4207
4208      sources = invoker.sources
4209      outputs = [ _srcjar_path ]
4210      args = [
4211               "--flatc",
4212               rebase_path(_flatc_bin, root_build_dir),
4213               "--import-dir",
4214               rebase_path(invoker.root_dir, root_build_dir),
4215               "--srcjar",
4216               rebase_path(_srcjar_path, root_build_dir),
4217             ] + rebase_path(sources, root_build_dir)
4218
4219      if (defined(invoker.flatc_include_dirs)) {
4220        foreach(_include_dir, invoker.flatc_include_dirs) {
4221          args += [
4222            "--import-dir",
4223            rebase_path(_include_dir, root_build_dir),
4224          ]
4225        }
4226      }
4227    }
4228
4229    android_library(target_name) {
4230      chromium_code = false
4231      sources = []
4232      srcjar_deps = [ ":${_template_name}__flatc_java" ]
4233      deps = [ "//third_party/flatbuffers:flatbuffers_java" ]
4234      if (defined(invoker.deps)) {
4235        deps += invoker.deps
4236      }
4237    }
4238  }
4239
4240  # Declare an Android library target for a prebuilt AAR.
4241  #
4242  # This target creates an Android library containing java code and Android
4243  # resources. For libraries without resources, it will not generate
4244  # corresponding android_resources targets.
4245  #
4246  # To avoid slowing down "gn gen", an associated .info file must be committed
4247  # along with the .aar file. In order to create this file, define the target
4248  # and then run once with the gn arg "update_android_aar_prebuilts = true".
4249  #
4250  # Variables
4251  #   aar_path: Path to the AAR.
4252  #   info_path: Path to the .aar.info file (generated via
4253  #       update_android_aar_prebuilts GN arg).
4254  #   proguard_configs: List of proguard configs to use in final apk step for
4255  #       any apk that depends on this library.
4256  #   ignore_aidl: Whether to ignore .aidl files found with the .aar.
4257  #   ignore_assets: Whether to ignore assets found in the .aar.
4258  #   ignore_manifest: Whether to ignore creating manifest.
4259  #   ignore_native_libraries: Whether to ignore .so files found in the .aar.
4260  #       See also extract_native_libraries.
4261  #   ignore_proguard_configs: Whether to ignore proguard configs.
4262  #   strip_resources: Whether to ignore android resources found in the .aar.
4263  #   custom_package: Java package for generated R.java files.
4264  #   extract_native_libraries: Whether to extract .so files found in the .aar.
4265  #       If the file contains .so, either extract_native_libraries or
4266  #       ignore_native_libraries must be set.
4267  #   TODO(jbudorick@): remove this arguments after crbug.com/522043 is fixed.
4268  #   requires_android: Whether this target can only be used for compiling
4269  #       Android related targets.
4270  #
4271  # Example
4272  #   android_aar_prebuilt("foo_java") {
4273  #     aar_path = "foo.aar"
4274  #   }
4275  template("android_aar_prebuilt") {
4276    _info_path = "$target_name.info"
4277    if (defined(invoker.info_path)) {
4278      _info_path = invoker.info_path
4279    }
4280    _output_path = "${target_out_dir}/${target_name}"
4281
4282    # Some targets only differ by _java with other targets so _java and _junit
4283    # need to be replaced by non-empty strings to avoid duplicate targets. (e.g.
4284    # androidx_window_window_java vs androidx_window_window_java_java).
4285    _target_name_without_java_or_junit =
4286        string_replace(string_replace(target_name, "_java", "_J"),
4287                       "_junit",
4288                       "_U")
4289
4290    # This unpack target is a python action, not a valid java target. Since the
4291    # java targets below depend on it, its name must not match the java patterns
4292    # in internal_rules.gni.
4293    _unpack_target_name = "${_target_name_without_java_or_junit}__unpack_aar"
4294    _ignore_aidl = defined(invoker.ignore_aidl) && invoker.ignore_aidl
4295    _ignore_assets = defined(invoker.ignore_assets) && invoker.ignore_assets
4296    _ignore_manifest =
4297        defined(invoker.ignore_manifest) && invoker.ignore_manifest
4298    _ignore_native_libraries = defined(invoker.ignore_native_libraries) &&
4299                               invoker.ignore_native_libraries
4300    _ignore_proguard_configs = defined(invoker.ignore_proguard_configs) &&
4301                               invoker.ignore_proguard_configs
4302    _extract_native_libraries = defined(invoker.extract_native_libraries) &&
4303                                invoker.extract_native_libraries
4304    _strip_resources =
4305        defined(invoker.strip_resources) && invoker.strip_resources
4306
4307    # Allow 'resource_overlay' parameter even if there are no resources in order
4308    # to keep the logic for generated 'android_aar_prebuilt' rules simple.
4309    not_needed(invoker, [ "resource_overlay" ])
4310
4311    _aar_common_args = [ rebase_path(invoker.aar_path, root_build_dir) ]
4312    if (_strip_resources) {
4313      _aar_common_args += [ "--ignore-resources" ]
4314    }
4315    if (defined(invoker.resource_exclusion_globs)) {
4316      _aar_common_args +=
4317          [ "--resource-exclusion-globs=${invoker.resource_exclusion_globs}" ]
4318    }
4319
4320    # Scan the AAR file and determine the resources and jar files.
4321    # Some libraries might not have resources; others might have two jars.
4322    if (update_android_aar_prebuilts) {
4323      print("Writing " + rebase_path(_info_path, "//"))
4324      exec_script("//build/android/gyp/aar.py",
4325                  [
4326                        "list",
4327                        "--output",
4328                        rebase_path(_info_path, root_build_dir),
4329                      ] + _aar_common_args)
4330    }
4331
4332    # If "gn gen" is failing on the following line, you need to generate an
4333    # .info file for your new target by running:
4334    #   gn gen --args='target_os="android" update_android_aar_prebuilts=true' out/tmp
4335    #   rm -r out/tmp
4336    _scanned_files = read_file(_info_path, "scope")
4337
4338    _use_scanned_assets = !_ignore_assets && _scanned_files.assets != []
4339    _has_resources = _scanned_files.resources != []
4340    _common_deps = [ ":$_unpack_target_name" ]
4341    if (defined(invoker.deps)) {
4342      _common_deps += invoker.deps
4343    }
4344    if (defined(invoker.public_deps)) {
4345      _common_deps += invoker.public_deps
4346    }
4347
4348    assert(_ignore_aidl || _scanned_files.aidl == [],
4349           "android_aar_prebuilt() aidl not yet supported." +
4350               " Implement or use ignore_aidl = true." +
4351               " http://crbug.com/644439")
4352    assert(
4353        !_scanned_files.has_native_libraries ||
4354            (_ignore_native_libraries || _extract_native_libraries),
4355        "android_aar_prebuilt() contains .so files." +
4356            " Please set ignore_native_libraries or extract_native_libraries.")
4357    assert(
4358        !(_ignore_native_libraries && _extract_native_libraries),
4359        "ignore_native_libraries and extract_native_libraries cannot both be set.")
4360    assert(!_scanned_files.has_native_libraries ||
4361           _scanned_files.native_libraries != [])
4362    assert(_scanned_files.has_classes_jar || _scanned_files.subjars == [])
4363
4364    action_with_pydeps(_unpack_target_name) {
4365      script = "//build/android/gyp/aar.py"  # Unzips the AAR
4366      args = [
4367               "extract",
4368               "--output-dir",
4369               rebase_path(_output_path, root_build_dir),
4370               "--assert-info-file",
4371               rebase_path(_info_path, root_build_dir),
4372             ] + _aar_common_args
4373      inputs = [ invoker.aar_path ]
4374      outputs = [ "${_output_path}/AndroidManifest.xml" ]
4375      outputs +=
4376          get_path_info(rebase_path(_scanned_files.resources, "", _output_path),
4377                        "abspath")
4378      if (_scanned_files.has_r_text_file) {
4379        # Certain packages, in particular Play Services have no R.txt even
4380        # though its presence is mandated by AAR spec. Such packages cause
4381        # spurious rebuilds if this output is specified unconditionally.
4382        outputs += [ "${_output_path}/R.txt" ]
4383      }
4384
4385      if (_scanned_files.has_classes_jar) {
4386        outputs += [ "${_output_path}/classes.jar" ]
4387      }
4388      outputs +=
4389          get_path_info(rebase_path(_scanned_files.subjars, "", _output_path),
4390                        "abspath")
4391      if (!_ignore_proguard_configs) {
4392        if (_scanned_files.has_proguard_flags) {
4393          outputs += [ "${_output_path}/proguard.txt" ]
4394        }
4395      }
4396
4397      if (_extract_native_libraries && _scanned_files.has_native_libraries) {
4398        outputs += get_path_info(
4399                rebase_path(_scanned_files.native_libraries, "", _output_path),
4400                "abspath")
4401      }
4402      if (_use_scanned_assets) {
4403        outputs +=
4404            get_path_info(rebase_path(_scanned_files.assets, "", _output_path),
4405                          "abspath")
4406      }
4407    }
4408
4409    _should_process_manifest =
4410        !_ignore_manifest && !_scanned_files.is_manifest_empty
4411
4412    # Create the android_resources target for resources.
4413    if (_has_resources || _should_process_manifest) {
4414      _res_target_name = "${target_name}__resources"
4415      android_resources(_res_target_name) {
4416        forward_variables_from(invoker,
4417                               [
4418                                 "custom_package",
4419                                 "resource_overlay",
4420                                 "testonly",
4421                                 "strip_drawables",
4422                               ])
4423        deps = _common_deps
4424        if (_should_process_manifest) {
4425          android_manifest_dep = ":$_unpack_target_name"
4426          android_manifest = "${_output_path}/AndroidManifest.xml"
4427        } else if (defined(_scanned_files.manifest_package) &&
4428                   !defined(custom_package)) {
4429          custom_package = _scanned_files.manifest_package
4430        }
4431
4432        sources = rebase_path(_scanned_files.resources, "", _output_path)
4433        if (_scanned_files.has_r_text_file) {
4434          r_text_file = "${_output_path}/R.txt"
4435        }
4436      }
4437    } else if (defined(invoker.strip_drawables)) {
4438      not_needed(invoker, [ "strip_drawables" ])
4439    }
4440
4441    if (_ignore_manifest) {
4442      # Having this available can be useful for DFMs that depend on AARs. It
4443      # provides a way to have manifest entries go into the base split while
4444      # the code goes into a DFM.
4445      java_group("${target_name}__ignored_manifest") {
4446        forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4447        deps = [ ":$_unpack_target_name" ]
4448        mergeable_android_manifests = [ "${_output_path}/AndroidManifest.xml" ]
4449      }
4450    }
4451
4452    # Create the android_assets target for assets
4453    if (_use_scanned_assets) {
4454      _assets_target_name = "${target_name}__assets"
4455      android_assets(_assets_target_name) {
4456        forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4457        deps = [ ":$_unpack_target_name" ]
4458        renaming_sources = []
4459        renaming_destinations = []
4460        foreach(_asset_file, _scanned_files.assets) {
4461          _original_path =
4462              get_path_info(rebase_path(_asset_file, "", _output_path),
4463                            "abspath")
4464          _updated_path = string_replace(_asset_file, "assets/", "", 1)
4465          renaming_sources += [ _original_path ]
4466          renaming_destinations += [ _updated_path ]
4467        }
4468      }
4469    }
4470
4471    _target_label = get_label_info(":$target_name", "label_no_toolchain")
4472
4473    # Create android_java_prebuilt target for classes.jar.
4474    if (_scanned_files.has_classes_jar) {
4475      _java_library_vars = [
4476        "alternative_android_sdk_dep",
4477        "bytecode_rewriter_target",
4478        "enable_bytecode_checks",
4479        "jar_excluded_patterns",
4480        "jar_included_patterns",
4481        "missing_classes_allowlist",
4482        "requires_android",
4483        "testonly",
4484      ]
4485
4486      # Create android_java_prebuilt target for extra jars within jars/.
4487      _subjar_targets = []
4488      foreach(_tuple, _scanned_files.subjar_tuples) {
4489        _current_target = "${target_name}__subjar_${_tuple[0]}"
4490        _subjar_targets += [ ":$_current_target" ]
4491        java_prebuilt(_current_target) {
4492          forward_variables_from(invoker, _java_library_vars)
4493          deps = _common_deps
4494          if (!defined(requires_android)) {
4495            requires_android = true
4496          }
4497          supports_android = true
4498          jar_path = "$_output_path/${_tuple[1]}"
4499          _base_output_name = get_path_info(jar_path, "name")
4500          output_name = "${invoker.target_name}-$_base_output_name"
4501          public_target_label = _target_label
4502        }
4503      }
4504
4505      _jar_target_name = "${target_name}__classes"
4506      java_prebuilt(_jar_target_name) {
4507        forward_variables_from(invoker, _java_library_vars)
4508        forward_variables_from(invoker,
4509                               [
4510                                 "input_jars_paths",
4511                                 "mergeable_android_manifests",
4512                                 "proguard_configs",
4513                               ])
4514        deps = _common_deps + _subjar_targets
4515        if (defined(_res_target_name)) {
4516          deps += [ ":$_res_target_name" ]
4517        }
4518        if (!defined(requires_android)) {
4519          requires_android = true
4520        }
4521        include_java_resources = !defined(invoker.include_java_resources) ||
4522                                 invoker.include_java_resources
4523        supports_android = true
4524        jar_path = "$_output_path/classes.jar"
4525        aar_path = invoker.aar_path
4526        output_name = invoker.target_name
4527
4528        if (!_ignore_proguard_configs) {
4529          if (!defined(proguard_configs)) {
4530            proguard_configs = []
4531          }
4532          if (_scanned_files.has_proguard_flags) {
4533            proguard_configs += [ "$_output_path/proguard.txt" ]
4534          }
4535        }
4536        public_target_label = _target_label
4537      }
4538    }
4539
4540    java_group(target_name) {
4541      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4542      public_deps = [ ":$_unpack_target_name" ]
4543      if (defined(invoker.public_deps)) {
4544        public_deps += invoker.public_deps
4545      }
4546      deps = []
4547      if (defined(_jar_target_name)) {
4548        deps += [ ":$_jar_target_name" ]
4549
4550        # Although subjars are meant to be private, we add them as deps here
4551        # because in practice they seem to contain classes required to be in the
4552        # classpath.
4553        deps += _subjar_targets
4554      }
4555      if (defined(_res_target_name)) {
4556        deps += [ ":$_res_target_name" ]
4557      }
4558      if (defined(_assets_target_name)) {
4559        deps += [ ":$_assets_target_name" ]
4560      }
4561    }
4562  }
4563
4564  # Create an Android application bundle from one base android_apk target,
4565  # and zero or more associated android_apk.
4566  #
4567  # Variables:
4568  #    base_module_target: Name of the android_app_bundle_module target
4569  #      corresponding to the base module for this application bundle. The
4570  #      bundle file will include the same content in its base module, though in
4571  #      a slightly different format.
4572  #
4573  #    bundle_base_path: Optional. If set, the bundle will be output to this
4574  #      directory. Defaults to "$root_build_dir/apks".
4575  #
4576  #    bundle_name: Optional. If set, the bundle will be output to the
4577  #      filename "${bundle_name}.aab".
4578  #
4579  #    extra_modules: Optional list of scopes, one per extra module used by
4580  #      this bundle. Each scope must have a 'name' field that specifies the
4581  #      module name (which cannot be 'base', since this is reserved for the
4582  #      base module), and an 'apk_target' field that specified the
4583  #      corresponding android_apk target name the module is modeled on.
4584  #
4585  #    enable_language_splits: Optional. If true, enable APK splits based
4586  #      on languages.
4587  #
4588  #    keystore_path: optional keystore path, used only when generating APKs.
4589  #    keystore_name: optional keystore name, used only when generating APKs.
4590  #    keystore_password: optional keystore password, used only when
4591  #      generating APKs.
4592  #    rotation_config: optional .textproto to enable key rotation.
4593  #
4594  #    command_line_flags_file: Optional. If provided, named of the on-device
4595  #      file that will be used to store command-line arguments. The default
4596  #      is 'command_line_flags_file', but this is typically redefined to
4597  #      something more specific for certain bundles (e.g. the Chromium based
4598  #      APKs use 'chrome-command-line', the WebView one uses
4599  #      'webview-command-line').
4600  #
4601  #    proguard_enabled: Optional. True if proguarding is enabled for this
4602  #      bundle. Default is to enable this only for release builds. Note that
4603  #      this will always perform synchronized proguarding.
4604  #
4605  #    proguard_enable_obfuscation: Whether to enable obfuscation (default=true)
4606  #
4607  #    proguard_android_sdk_dep: Optional. android_system_java_prebuilt() target
4608  #      used as a library jar for synchronized proguarding.
4609  #
4610  #    system_image_locale_allowlist: List of locales that should be included
4611  #      on system APKs generated from this bundle.
4612  #
4613  #    static_library_provider: Specifies a single target that this target will
4614  #      use as a static library APK.
4615  #
4616  #    expected_libs_and_assets: Verify the list of included native libraries
4617  #      and assets is consistent with the given expectation file.
4618  #    expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff
4619  #      with this file as the base.
4620  #    expected_proguard_config: Checks that the merged set of proguard flags
4621  #      matches the given config.
4622  #    expected_proguard_config_base: Treat expected_proguard_config as a diff
4623  #      with this file as the base.
4624  #
4625  #    version_code: Optional. Version code of the target.
4626  #
4627  #    is_multi_abi: If true will add a library placeholder for the missing ABI
4628  #      if either the primary or the secondary ABI has no native libraries set.
4629  #
4630  #    default_modules_for_testing: (optional): A list of DFM that the wrapper
4631  #      script should install. This is for local testing only, and does not
4632  #      affect the actual DFM in production.
4633  #
4634  #    add_view_trace_events: (optional): If true will add an additional step to
4635  #      add trace events to all Android views contained in the bundle. It also
4636  #      requires build argument enable_trace_event_bytecode_rewriting = true.
4637  #
4638  # Example:
4639  #   android_app_bundle("chrome_public_bundle") {
4640  #      base_module_target = "//chrome/android:chrome_public_apk"
4641  #      extra_modules = [
4642  #        { # NOTE: Scopes require one field per line, and no comma separators.
4643  #          name = "my_module"
4644  #          module_target = ":my_module"
4645  #        },
4646  #      ]
4647  #   }
4648  #
4649  template("android_app_bundle") {
4650    _target_name = target_name
4651    _uses_static_library = defined(invoker.static_library_provider)
4652    _proguard_enabled =
4653        defined(invoker.proguard_enabled) && invoker.proguard_enabled
4654
4655    _min_sdk_version = default_min_sdk_version
4656    if (defined(invoker.min_sdk_version)) {
4657      _min_sdk_version = invoker.min_sdk_version
4658    }
4659    if (is_asan && _min_sdk_version < min_supported_sdk_version) {
4660      _min_sdk_version = min_supported_sdk_version
4661    }
4662
4663    _bundle_base_path = "$root_build_dir/apks"
4664    if (defined(invoker.bundle_base_path)) {
4665      _bundle_base_path = invoker.bundle_base_path
4666    }
4667
4668    _bundle_name = _target_name
4669    if (defined(invoker.bundle_name)) {
4670      _bundle_name = invoker.bundle_name
4671    }
4672    _bundle_path = "$_bundle_base_path/${_bundle_name}.aab"
4673    _rebased_bundle_path = rebase_path(_bundle_path, root_build_dir)
4674
4675    _base_target_name = get_label_info(invoker.base_module_target, "name")
4676    _base_target_gen_dir =
4677        get_label_info(invoker.base_module_target, "target_gen_dir")
4678    _base_module_build_config =
4679        "$_base_target_gen_dir/${_base_target_name}.build_config.json"
4680    _base_module_build_config_target =
4681        "${invoker.base_module_target}$build_config_target_suffix"
4682    _rebased_base_module_build_config =
4683        rebase_path(_base_module_build_config, root_build_dir)
4684
4685    _modules = [
4686      {
4687        name = "base"
4688        module_target = invoker.base_module_target
4689        build_config = _base_module_build_config
4690        build_config_target = _base_module_build_config_target
4691        if (_uses_static_library) {
4692          parent = "lib"
4693        }
4694      },
4695    ]
4696
4697    if (_proguard_enabled) {
4698      _dex_target = "${_target_name}__dex"
4699      _proguard_mapping_path = "${_bundle_path}.mapping"
4700    }
4701
4702    if (defined(invoker.extra_modules)) {
4703      _module_count = 0
4704      not_needed([ "_module_count" ])
4705
4706      foreach(_module, invoker.extra_modules) {
4707        _module_count += 1
4708        assert(defined(_module.name),
4709               "Missing 'name' field for extra module #${_module_count}.")
4710        assert(_module.name != "base",
4711               "Module name 'base' is reserved for the main bundle module")
4712        assert(
4713            defined(_module.module_target),
4714            "Missing 'module_target' field for extra module ${_module.name}.")
4715        _module_target = _module.module_target
4716        _module_target_name = get_label_info(_module_target, "name")
4717        _module_target_gen_dir =
4718            get_label_info(_module_target, "target_gen_dir")
4719        _module.build_config =
4720            "$_module_target_gen_dir/${_module_target_name}.build_config.json"
4721        _module.build_config_target =
4722            "$_module_target$build_config_target_suffix"
4723        _module.parent = "base"
4724        _modules += [ _module ]
4725      }
4726    }
4727
4728    # Make build config, which is required for synchronized proguarding.
4729    _module_java_targets = []
4730    _module_build_configs = []
4731    _module_targets = []
4732    foreach(_module, _modules) {
4733      _module_targets += [ _module.module_target ]
4734      _module_java_targets += [ "${_module.module_target}__java" ]
4735      _module_build_configs += [ _module.build_config ]
4736    }
4737
4738    # Used to expose the module Java targets of the bundle.
4739    group("${_target_name}__java") {
4740      deps = _module_java_targets
4741    }
4742    group("${_target_name}__compile_resources") {
4743      deps = [ "${invoker.base_module_target}__compile_resources" ]
4744    }
4745
4746    _build_config = "$target_gen_dir/${_target_name}.build_config.json"
4747    _rebased_build_config = rebase_path(_build_config, root_build_dir)
4748    _build_config_target = "$_target_name$build_config_target_suffix"
4749    if (defined(invoker.proguard_android_sdk_dep)) {
4750      _android_sdk_dep = invoker.proguard_android_sdk_dep
4751    } else {
4752      _android_sdk_dep = default_android_sdk_dep
4753    }
4754
4755    if (_proguard_enabled) {
4756      _proguard_mapping_path = "${_bundle_path}.mapping"
4757      _add_view_trace_events =
4758          defined(invoker.add_view_trace_events) &&
4759          invoker.add_view_trace_events && enable_trace_event_bytecode_rewriting
4760    } else {
4761      not_needed(invoker, [ "add_view_trace_events" ])
4762    }
4763
4764    write_build_config(_build_config_target) {
4765      type = "android_app_bundle"
4766      possible_config_deps = _module_targets + [ _android_sdk_dep ]
4767      build_config = _build_config
4768      proguard_enabled = _proguard_enabled
4769      module_build_configs = _module_build_configs
4770      modules = _modules
4771
4772      if (_proguard_enabled) {
4773        add_view_trace_events = _add_view_trace_events
4774        proguard_mapping_path = _proguard_mapping_path
4775      }
4776    }
4777
4778    # Old name for variable, mark as not_needed while it is being renamed
4779    # downstream. Remove after all references to baseline_profile_path have been
4780    # changed.
4781    not_needed(invoker, [ "baseline_profile_path" ])
4782
4783    _enable_art_profile_optimizations =
4784        defined(invoker.art_profile_path) && _proguard_enabled
4785
4786    if (_enable_art_profile_optimizations) {
4787      _include_baseline_profile = enable_baseline_profiles
4788      _enable_startup_profile = enable_startup_profiles
4789      if (_include_baseline_profile) {
4790        _obfuscated_art_profile =
4791            "$target_out_dir/${target_name}.obfuscated.hrf"
4792      }
4793    } else {
4794      not_needed(invoker, [ "art_profile_path" ])
4795    }
4796
4797    if (_proguard_enabled) {
4798      if (_add_view_trace_events) {
4799        _trace_event_rewriter_target =
4800            "//build/android/bytecode:trace_event_adder"
4801        _rewritten_jar_target_name = "${target_name}__trace_event_rewritten"
4802        _rewriter_path = root_build_dir + "/bin/helper/trace_event_adder"
4803        _stamp = "${target_out_dir}/${target_name}.trace_event_rewrite.stamp"
4804        action_with_pydeps(_rewritten_jar_target_name) {
4805          script = "//build/android/gyp/trace_event_bytecode_rewriter.py"
4806          inputs = java_paths_for_inputs + [
4807                     _rewriter_path,
4808                     _build_config,
4809                   ]
4810          outputs = [ _stamp ]
4811          depfile = "$target_gen_dir/$_rewritten_jar_target_name.d"
4812          args = [
4813            "--stamp",
4814            rebase_path(_stamp, root_build_dir),
4815            "--depfile",
4816            rebase_path(depfile, root_build_dir),
4817            "--script",
4818            rebase_path(_rewriter_path, root_build_dir),
4819            "--classpath",
4820            "@FileArg($_rebased_build_config:android:sdk_jars)",
4821            "--input-jars",
4822            "@FileArg($_rebased_build_config:deps_info:device_classpath)",
4823            "--output-jars",
4824            "@FileArg($_rebased_build_config:deps_info:trace_event_rewritten_device_classpath)",
4825          ]
4826          deps = [
4827                   ":$_build_config_target",
4828                   _trace_event_rewriter_target,
4829                 ] + _module_java_targets
4830        }
4831      }
4832
4833      dex(_dex_target) {
4834        forward_variables_from(invoker,
4835                               [
4836                                 "custom_assertion_handler",
4837                                 "expected_proguard_config",
4838                                 "expected_proguard_config_base",
4839                                 "proguard_enable_obfuscation",
4840                                 "repackage_classes",
4841                               ])
4842        if (defined(expected_proguard_config)) {
4843          top_target_name = _target_name
4844        }
4845        min_sdk_version = _min_sdk_version
4846        add_view_trace_events = _add_view_trace_events
4847        proguard_enabled = true
4848        proguard_mapping_path = _proguard_mapping_path
4849        build_config = _build_config
4850        if (_enable_art_profile_optimizations) {
4851          input_art_profile = invoker.art_profile_path
4852          if (_include_baseline_profile) {
4853            output_art_profile = _obfuscated_art_profile
4854          }
4855          enable_startup_profile = _enable_startup_profile
4856        }
4857
4858        deps = _module_java_targets + [ ":$_build_config_target" ]
4859        if (_add_view_trace_events) {
4860          deps += [ ":${_rewritten_jar_target_name}" ]
4861        }
4862        modules = _modules
4863
4864        # Must not be set via write_build_config, because that will cause it
4865        # to be picked up by test apks that use apk_under_test.
4866        _assertions_implicitly_enabled =
4867            defined(invoker.custom_assertion_handler)
4868        if (!_assertions_implicitly_enabled && !enable_java_asserts &&
4869            (!defined(testonly) || !testonly) &&
4870            # Injected JaCoCo code causes -checkdiscards to fail.
4871            !use_jacoco_coverage) {
4872          proguard_configs = [
4873            "//build/android/dcheck_is_off.flags",
4874            "//third_party/jni_zero/checkdiscard_proguard.flags",
4875          ]
4876        }
4877      }
4878    }
4879
4880    _all_create_module_targets = []
4881    _all_module_zip_paths = []
4882    _all_module_build_configs = []
4883    _all_module_unused_resources_deps = []
4884    foreach(_module, _modules) {
4885      _module_target = _module.module_target
4886      _module_build_config = _module.build_config
4887      _module_build_config_target = _module.build_config_target
4888
4889      if (!_proguard_enabled) {
4890        _module_target_name = get_label_info(_module_target, "name")
4891        _dex_target = "${_module_target_name}__final_dex"
4892        _dex_path = "$target_out_dir/$_module_target_name/$_module_target_name.mergeddex.jar"
4893        dex(_dex_target) {
4894          forward_variables_from(invoker, [ "custom_assertion_handler" ])
4895          min_sdk_version = _min_sdk_version
4896          output = _dex_path
4897          build_config = _build_config
4898
4899          # This will be a pure dex-merge.
4900          input_dex_filearg = "@FileArg($_rebased_build_config:modules:${_module.name}:all_dex_files)"
4901          enable_desugar = false
4902
4903          deps = [
4904            ":$_build_config_target",
4905            ":${_module_target_name}__java",
4906          ]
4907        }
4908      }
4909      _dex_target_for_module = ":$_dex_target"
4910
4911      if (_enable_art_profile_optimizations && _include_baseline_profile) {
4912        _module_target_name = get_label_info(_module_target, "name")
4913        _binary_profile_target =
4914            "${_module_target_name}__binary_baseline_profile"
4915        _binary_baseline_profile_path = "$target_out_dir/$_module_target_name/$_module_target_name.baseline.prof"
4916        _binary_baseline_profile_metadata_path =
4917            _binary_baseline_profile_path + "m"
4918        create_binary_profile(_binary_profile_target) {
4919          forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4920          binary_baseline_profile_path = _binary_baseline_profile_path
4921          binary_baseline_profile_metadata_path =
4922              _binary_baseline_profile_metadata_path
4923          build_config = _module_build_config
4924          input_profile_path = _obfuscated_art_profile
4925          deps = [
4926            _dex_target_for_module,
4927            _module_build_config_target,
4928          ]
4929        }
4930      }
4931
4932      # Generate one module .zip file per bundle module.
4933      #
4934      # Important: the bundle tool uses the module's zip filename as
4935      # the internal module name inside the final bundle, in other words,
4936      # this file *must* be named ${_module.name}.zip
4937      _create_module_target = "${_target_name}__${_module.name}__create"
4938      _module_zip_path = "$target_out_dir/$target_name/${_module.name}.zip"
4939      create_android_app_bundle_module(_create_module_target) {
4940        forward_variables_from(invoker,
4941                               [
4942                                 "is_multi_abi",
4943                                 "uncompress_dex",
4944                               ])
4945        module_name = _module.name
4946        min_sdk_version = _min_sdk_version
4947        build_config = _module_build_config
4948        module_zip_path = _module_zip_path
4949        if (!_proguard_enabled) {
4950          dex_path = _dex_path
4951          # dex_path is read from the build_config in the proguard case.
4952        }
4953
4954        if (module_name == "base" &&
4955            defined(invoker.expected_libs_and_assets)) {
4956          forward_variables_from(invoker,
4957                                 [
4958                                   "expected_libs_and_assets",
4959                                   "expected_libs_and_assets_base",
4960                                 ])
4961          top_target_name = _target_name
4962          build_config_target = _module_build_config_target
4963        }
4964
4965        deps = [
4966          _dex_target_for_module,
4967          _module_build_config_target,
4968          _module_target,
4969        ]
4970
4971        if (_enable_art_profile_optimizations && _include_baseline_profile) {
4972          # extra_assets is a list of ["{src_path}:{dst_path}"]
4973          extra_assets = [
4974            rebase_path(_binary_baseline_profile_path, root_build_dir) +
4975                ":dexopt/baseline.prof",
4976            rebase_path(_binary_baseline_profile_metadata_path,
4977                        root_build_dir) + ":dexopt/baseline.profm",
4978          ]
4979          deps += [ ":$_binary_profile_target" ]
4980        }
4981      }
4982
4983      _all_create_module_targets += [
4984        ":$_create_module_target",
4985        _module_build_config_target,
4986        "${_module_target}__compile_resources",
4987      ]
4988      _all_module_zip_paths += [ _module_zip_path ]
4989      _all_module_build_configs += [ _module_build_config ]
4990      _all_module_unused_resources_deps += [
4991        "${_module_target}__compile_resources",
4992        _dex_target_for_module,
4993        _module_build_config_target,
4994      ]
4995    }
4996    _strip_unused_resources = defined(invoker.strip_unused_resources) &&
4997                              invoker.strip_unused_resources
4998    if (_strip_unused_resources) {
4999      # Resources only live in the base module so we define the unused resources
5000      # target only on the base module target.
5001      _unused_resources_target = "${_base_target_name}__unused_resources"
5002      _unused_resources_config =
5003          "${_base_target_gen_dir}/${_base_target_name}_unused_resources.config"
5004      _unused_resources_r_txt_out =
5005          "${_base_target_gen_dir}/${_base_target_name}_unused_resources.R.txt"
5006      unused_resources(_unused_resources_target) {
5007        deps = _all_module_unused_resources_deps
5008        all_module_build_configs = _all_module_build_configs
5009        build_config = _base_module_build_config
5010        if (_proguard_enabled) {
5011          proguard_mapping_path = _proguard_mapping_path
5012        }
5013        output_config = _unused_resources_config
5014        output_r_txt = _unused_resources_r_txt_out
5015      }
5016      _unused_resources_final_path = "${_bundle_path}.unused_resources"
5017      _copy_unused_resources_target =
5018          "${_base_target_name}__copy_unused_resources"
5019      copy(_copy_unused_resources_target) {
5020        deps = [ ":$_unused_resources_target" ]
5021        sources = [ _unused_resources_config ]
5022        outputs = [ _unused_resources_final_path ]
5023      }
5024    }
5025
5026    _all_rebased_module_zip_paths =
5027        rebase_path(_all_module_zip_paths, root_build_dir)
5028
5029    _enable_language_splits = defined(invoker.enable_language_splits) &&
5030                              invoker.enable_language_splits
5031
5032    _split_dimensions = []
5033    if (_enable_language_splits) {
5034      _split_dimensions += [ "language" ]
5035    }
5036
5037    _keystore_path = android_keystore_path
5038    _keystore_password = android_keystore_password
5039    _keystore_name = android_keystore_name
5040
5041    if (defined(invoker.keystore_path)) {
5042      _keystore_path = invoker.keystore_path
5043      _keystore_password = invoker.keystore_password
5044      _keystore_name = invoker.keystore_name
5045    }
5046
5047    _rebased_keystore_path = rebase_path(_keystore_path, root_build_dir)
5048
5049    _bundle_target_name = "${_target_name}__bundle"
5050    action_with_pydeps(_bundle_target_name) {
5051      script = "//build/android/gyp/create_app_bundle.py"
5052      inputs = _all_module_zip_paths + _all_module_build_configs +
5053               [ _BUNDLETOOL_JAR_PATH ] + java_paths_for_inputs
5054      outputs = [ _bundle_path ]
5055      deps = _all_create_module_targets + [ ":$_build_config_target" ]
5056      args = [
5057        "--out-bundle=$_rebased_bundle_path",
5058        "--rtxt-out-path=$_rebased_bundle_path.R.txt",
5059        "--pathmap-out-path=$_rebased_bundle_path.pathmap.txt",
5060        "--module-zips=$_all_rebased_module_zip_paths",
5061      ]
5062      if (_split_dimensions != []) {
5063        args += [ "--split-dimensions=$_split_dimensions" ]
5064      }
5065
5066      # Android P+ support loading from stored dex.
5067      if (_min_sdk_version < 27) {
5068        args += [ "--compress-dex" ]
5069      }
5070
5071      if (defined(invoker.rotation_config)) {
5072        args += [
5073          "--rotation-config",
5074          rebase_path(invoker.rotation_config, root_build_dir),
5075        ]
5076      }
5077
5078      if (treat_warnings_as_errors) {
5079        args += [ "--warnings-as-errors" ]
5080      }
5081
5082      if (_enable_language_splits) {
5083        args += [ "--base-allowlist-rtxt-path=@FileArg($_rebased_base_module_build_config:deps_info:base_allowlist_rtxt_path)" ]
5084        if (_strip_unused_resources) {
5085          # Use the stripped out rtxt file to set resources that are pinned to
5086          # the default language split.
5087          _rebased_unused_resources_r_txt_out =
5088              rebase_path(_unused_resources_r_txt_out, root_build_dir)
5089          inputs += [ _unused_resources_r_txt_out ]
5090          deps += [ ":$_unused_resources_target" ]
5091          args +=
5092              [ "--base-module-rtxt-path=$_rebased_unused_resources_r_txt_out" ]
5093        } else {
5094          args += [ "--base-module-rtxt-path=@FileArg($_rebased_base_module_build_config:deps_info:r_text_path)" ]
5095        }
5096      }
5097      if (defined(invoker.validate_services) && invoker.validate_services) {
5098        args += [ "--validate-services" ]
5099      }
5100
5101      foreach(_module, _modules) {
5102        _rebased_build_config =
5103            rebase_path(_module.build_config, root_build_dir)
5104        args += [
5105          "--uncompressed-assets=@FileArg(" +
5106              "$_rebased_build_config:deps_info:uncompressed_assets)",
5107          "--rtxt-in-paths=@FileArg(" +
5108              "$_rebased_build_config:deps_info:r_text_path)",
5109          "--pathmap-in-paths=@FileArg(" +
5110              "$_rebased_build_config:deps_info:module_pathmap_path)",
5111          "--module-name=" + _module.name,
5112        ]
5113      }
5114
5115      # http://crbug.com/725224. Fix for bots running out of memory.
5116      if (defined(java_cmd_pool_size)) {
5117        pool = "//build/config/android:java_cmd_pool($default_toolchain)"
5118      } else {
5119        pool = "//build/toolchain:link_pool($default_toolchain)"
5120      }
5121    }
5122
5123    # Create size info files for targets that care about size
5124    # (have proguard enabled).
5125    if (_proguard_enabled) {
5126      # Merge all module targets to obtain size info files for all targets.
5127      _all_module_targets = _module_targets
5128
5129      _size_info_target = "${_target_name}__size_info"
5130      create_size_info_files(_size_info_target) {
5131        name = "$_bundle_name.aab"
5132        deps = _all_module_targets + [ ":$_build_config_target" ]
5133        module_build_configs = _all_module_build_configs
5134      }
5135    }
5136
5137    if (_uses_static_library) {
5138      _install_artifacts_target = "${target_name}__install_artifacts"
5139      _install_artifacts_json =
5140          "${target_gen_dir}/${target_name}.install_artifacts"
5141      generated_file(_install_artifacts_target) {
5142        output_conversion = "json"
5143        deps = [ invoker.static_library_provider ]
5144        outputs = [ _install_artifacts_json ]
5145        data_keys = [ "install_artifacts" ]
5146        rebase = root_build_dir
5147      }
5148    }
5149
5150    # Generate a wrapper script for the bundle.
5151    _android_aapt2_path = android_sdk_tools_bundle_aapt2
5152
5153    _bundle_apks_path = "$_bundle_base_path/$_bundle_name.apks"
5154    _bundle_wrapper_script_dir = "$root_build_dir/bin"
5155    _bundle_wrapper_script_path = "$_bundle_wrapper_script_dir/$_target_name"
5156
5157    action_with_pydeps("${_target_name}__wrapper_script") {
5158      script = "//build/android/gyp/create_bundle_wrapper_script.py"
5159      inputs = [ _base_module_build_config ]
5160      outputs = [ _bundle_wrapper_script_path ]
5161
5162      # Telemetry for bundles uses the wrapper script for installation.
5163      data = [
5164        _bundle_wrapper_script_path,
5165        _android_aapt2_path,
5166        _keystore_path,
5167        _bundle_path,
5168      ]
5169      data_deps = [
5170        "//build/android:apk_operations_py",
5171        "//build/android:stack_tools",
5172      ]
5173
5174      deps = [ _base_module_build_config_target ]
5175      args = [
5176        "--script-output-path",
5177        rebase_path(_bundle_wrapper_script_path, root_build_dir),
5178        "--package-name=@FileArg($_rebased_base_module_build_config:deps_info:package_name)",
5179        "--aapt2",
5180        rebase_path(_android_aapt2_path, root_build_dir),
5181        "--bundle-path",
5182        _rebased_bundle_path,
5183        "--bundle-apks-path",
5184        rebase_path(_bundle_apks_path, root_build_dir),
5185        "--target-cpu=$target_cpu",
5186        "--keystore-path",
5187        _rebased_keystore_path,
5188        "--keystore-password",
5189        _keystore_password,
5190        "--key-name",
5191        _keystore_name,
5192      ]
5193      if (defined(invoker.default_modules_for_testing)) {
5194        args += [ "--default-modules" ] + invoker.default_modules_for_testing
5195      }
5196      if (defined(invoker.system_image_locale_allowlist)) {
5197        args += [
5198          "--system-image-locales=${invoker.system_image_locale_allowlist}",
5199        ]
5200      }
5201      if (defined(invoker.command_line_flags_file)) {
5202        args += [
5203          "--command-line-flags-file",
5204          invoker.command_line_flags_file,
5205        ]
5206      }
5207      if (_uses_static_library) {
5208        deps += [ ":$_install_artifacts_target" ]
5209        _rebased_install_artifacts_json =
5210            rebase_path(_install_artifacts_json, root_build_dir)
5211        _static_library_apk_path =
5212            "@FileArg($_rebased_install_artifacts_json[])"
5213        args += [
5214          "--additional-apk",
5215          _static_library_apk_path,
5216        ]
5217      }
5218
5219      if (_proguard_enabled) {
5220        args += [
5221          "--proguard-mapping-path",
5222          rebase_path(_proguard_mapping_path, root_build_dir),
5223        ]
5224
5225        # Required by logcat command.
5226        data_deps += [ "//build/android/stacktrace:java_deobfuscate" ]
5227        data += [ _proguard_mapping_path ]
5228      }
5229      if (is_official_build) {
5230        args += [ "--is-official-build" ]
5231      }
5232    }
5233
5234    _enable_lint = defined(invoker.enable_lint) && invoker.enable_lint &&
5235                   !disable_android_lint
5236    if (_enable_lint) {
5237      android_lint("${target_name}__lint") {
5238        forward_variables_from(invoker,
5239                               [
5240                                 "lint_baseline_file",
5241                                 "lint_gen_dir",
5242                                 "lint_jar_path",
5243                                 "lint_suppressions_file",
5244                               ])
5245        build_config = _build_config
5246        build_config_dep = ":$_build_config_target"
5247        deps = _module_java_targets
5248        if (defined(invoker.lint_suppressions_dep)) {
5249          deps += [ invoker.lint_suppressions_dep ]
5250        }
5251        if (defined(invoker.lint_min_sdk_version)) {
5252          min_sdk_version = invoker.lint_min_sdk_version
5253        } else {
5254          min_sdk_version = _min_sdk_version
5255        }
5256      }
5257    } else {
5258      not_needed(invoker,
5259                 [
5260                   "lint_baseline_file",
5261                   "lint_gen_dir",
5262                   "lint_jar_path",
5263                   "lint_min_sdk_version",
5264                   "lint_suppressions_dep",
5265                   "lint_suppressions_file",
5266                 ])
5267    }
5268
5269    group(_target_name) {
5270      public_deps = [
5271        ":$_bundle_target_name",
5272        ":${_target_name}__wrapper_script",
5273      ]
5274      if (defined(_size_info_target)) {
5275        public_deps += [ ":$_size_info_target" ]
5276      }
5277      if (_enable_lint) {
5278        if (!defined(data_deps)) {
5279          data_deps = []
5280        }
5281        data_deps += [ ":${target_name}__lint" ]
5282      }
5283    }
5284
5285    _apks_path = "$root_build_dir/apks/$_bundle_name.apks"
5286    action_with_pydeps("${_target_name}_apks") {
5287      script = "//build/android/gyp/create_app_bundle_apks.py"
5288      inputs = java_paths_for_inputs + [
5289                 _bundle_path,
5290                 _BUNDLETOOL_JAR_PATH,
5291               ]
5292      outputs = [ _apks_path ]
5293      data = [ _apks_path ]
5294      args = [
5295        "--bundle",
5296        _rebased_bundle_path,
5297        "--output",
5298        rebase_path(_apks_path, root_build_dir),
5299        "--aapt2-path",
5300        rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
5301        "--keystore-path",
5302        rebase_path(android_keystore_path, root_build_dir),
5303        "--keystore-name",
5304        android_keystore_name,
5305        "--keystore-password",
5306        android_keystore_password,
5307      ]
5308      if (debuggable_apks) {
5309        args += [ "--local-testing" ]
5310      }
5311      deps = [ ":$_bundle_target_name" ]
5312      metadata = {
5313        install_artifacts = [ _apks_path ]
5314        if (defined(invoker.static_library_provider)) {
5315          install_artifacts_barrier = []
5316        }
5317      }
5318
5319      # http://crbug.com/725224. Fix for bots running out of memory.
5320      if (defined(java_cmd_pool_size)) {
5321        pool = "//build/config/android:java_cmd_pool($default_toolchain)"
5322      } else {
5323        pool = "//build/toolchain:link_pool($default_toolchain)"
5324      }
5325    }
5326  }
5327
5328  # Create an .apks file from an .aab file. The .apks file will contain the
5329  # minimal set of .apk files needed for tracking binary size.
5330  # The file will be created at "$bundle_path_without_extension.minimal.apks".
5331  #
5332  # Variables:
5333  #   bundle_path: Path to the input .aab file.
5334  #
5335  # Example:
5336  #   create_app_bundle_minimal_apks("minimal_apks") {
5337  #     deps = [
5338  #       ":bundle_target",
5339  #     ]
5340  #     bundle_path = "$root_build_dir/apks/Bundle.aab"
5341  #   }
5342  template("create_app_bundle_minimal_apks") {
5343    action_with_pydeps(target_name) {
5344      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
5345      script = "//build/android/gyp/create_app_bundle_apks.py"
5346      _dir = get_path_info(invoker.bundle_path, "dir")
5347      _name = get_path_info(invoker.bundle_path, "name")
5348      _output_path = "$_dir/$_name.minimal.apks"
5349      outputs = [ _output_path ]
5350      inputs = [ invoker.bundle_path ] + java_paths_for_inputs
5351      args = [
5352        "--bundle",
5353        rebase_path(invoker.bundle_path, root_build_dir),
5354        "--output",
5355        rebase_path(_output_path, root_build_dir),
5356        "--aapt2-path",
5357        rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
5358        "--keystore-path",
5359        rebase_path(android_keystore_path, root_build_dir),
5360        "--keystore-name",
5361        android_keystore_name,
5362        "--keystore-password",
5363        android_keystore_password,
5364        "--minimal",
5365      ]
5366    }
5367  }
5368
5369  template("alias_with_wrapper_script") {
5370    copy(target_name) {
5371      _aliased_wrapper_script_name =
5372          get_label_info(invoker.alias_target, "name")
5373      _aliased_wrapper_script =
5374          "$root_build_dir/bin/$_aliased_wrapper_script_name"
5375      sources = [ _aliased_wrapper_script ]
5376      deps = [ invoker.alias_target ]
5377
5378      _output_path = "$root_build_dir/bin/$target_name"
5379      outputs = [ _output_path ]
5380    }
5381  }
5382
5383  # Generate an Android resources target that contains localized strings
5384  # describing the current locale used by the Android framework to display
5385  # UI strings. These are used by
5386  # org.chromium.chrome.browser.ChromeLocalizationUtils.
5387  #
5388  # Variables:
5389  #    ui_locales: List of Chromium locale names to generate resources for.
5390  #
5391  template("generate_ui_locale_resources") {
5392    _generating_target_name = "${target_name}__generate"
5393    _rebased_output_zip_path = rebase_path(target_gen_dir, root_gen_dir)
5394    _output_zip = "${root_out_dir}/resource_zips/${_rebased_output_zip_path}/" +
5395                  "${target_name}.zip"
5396
5397    action_with_pydeps(_generating_target_name) {
5398      script = "//build/android/gyp/create_ui_locale_resources.py"
5399      outputs = [ _output_zip ]
5400      args = [
5401        "--locale-list=${invoker.ui_locales}",
5402        "--output-zip",
5403        rebase_path(_output_zip, root_build_dir),
5404      ]
5405    }
5406
5407    android_generated_resources(target_name) {
5408      generating_target = ":$_generating_target_name"
5409      generated_resources_zip = _output_zip
5410    }
5411  }
5412}
5413