• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# Do not add any imports to non-//build directories here.
6# Some projects (e.g. V8) do not have non-build directories DEPS'ed in.
7import("//build/config/android/channel.gni")
8import("//build/config/android/config.gni")
9import("//build/config/compiler/compiler.gni")
10import("//build/config/compute_inputs_for_analyze.gni")
11import("//build/config/coverage/coverage.gni")
12import("//build/config/python.gni")
13import("//build/config/sanitizers/sanitizers.gni")
14import("//build/toolchain/kythe.gni")
15import("//build/util/generate_wrapper.gni")
16import("//build_overrides/build.gni")
17if (current_toolchain == default_toolchain) {
18  import("//build/toolchain/concurrent_links.gni")
19}
20assert(is_android)
21
22default_android_sdk_dep = "//third_party/android_sdk:android_sdk_java"
23_kotlin_stdlib_dep = "//third_party/kotlin_stdlib:kotlin_stdlib_java"
24_jacoco_dep = "//third_party/jacoco:jacocoagent_java"
25_jacoco_host_jar =
26    "$root_build_dir/lib.java/third_party/jacoco/jacocoagent_java.jar"
27_robolectric_libs_dir =
28    rebase_path(
29        get_label_info("//:foo($robolectric_toolchain)", "root_out_dir"),
30        root_build_dir)
31_nullaway_jar = "//third_party/android_build_tools/nullaway/cipd/nullaway.jar"
32_rebased_nullaway_jar = rebase_path(_nullaway_jar, root_build_dir)
33
34# The following _java_*_types variables capture all the existing target types.
35# If a new type is introduced, please add it to one of these categories,
36# preferring the more specific resource/library types.
37_java_resource_types = [
38  "android_assets",
39  "android_resources",
40]
41
42_java_library_types = [
43  "java_library",
44  "system_java_library",
45  "android_app_bundle_module",
46]
47
48# These are leaf java target types. They cannot be passed as deps to other
49# targets. Thus their naming schemes are not enforced.
50_java_leaf_types = [
51  "android_apk",
52  "android_app_bundle",
53  "dist_aar",
54  "dist_jar",
55  "java_annotation_processor",
56  "java_binary",
57  "robolectric_binary",
58]
59
60# All _java_resource_types targets must conform to these patterns.
61java_resource_patterns = [
62  "*_assets",
63  "*_grd",
64  "*_java_strings",
65  "*locale_paks",
66  "*_resources",
67  "*strings_java",
68  "*android*:assets",
69  "*:*_apk_*resources",
70  "*android*:resources",
71]
72
73# All _java_library_types targets must conform to these patterns. This includes
74# all non-leaf targets that use java_library_impl.
75java_library_patterns = [
76  "*_java",
77  "*_javalib",
78  "*javatests",
79  "*_bundle_module",
80  "*:*_java_*",  # E.g. chrome_java_test_support
81  "*:java",
82  "*/java",  # to allow filtering without expanding labels //a/java ->
83             # //a/java:java
84  "*:junit",
85  "*/junit",
86  "*:junit_*",
87  "*:*_junit_*",
88
89  # TODO(agrieve): Rename to glue_java
90  "//android_webview/glue",
91  "//android_webview/glue:glue",
92]
93
94# These identify all non-leaf targets that have .build_config.json files. This is the
95# set of patterns that other targets can use to filter out java targets.
96java_target_patterns = java_library_patterns + java_resource_patterns
97
98_r8_path = "//third_party/r8/cipd/lib/r8.jar"
99_custom_r8_path = "//third_party/r8/custom_r8.jar"
100
101# This duplication is intentional, so we avoid updating the r8.jar used by
102# dexing unless necessary, since each update invalidates all incremental dexing
103# and unnecessarily slows down all bots.
104_d8_path = "//third_party/r8/d8/cipd/lib/r8.jar"
105_custom_d8_path = "//third_party/r8/custom_d8.jar"
106_default_lint_jar_path = "//third_party/android_build_tools/lint/cipd/lint.jar"
107_custom_lint_jar_path = "//third_party/android_build_tools/lint/custom_lint.jar"
108_manifest_merger_jar_path =
109    "//third_party/android_build_tools/manifest_merger/cipd/manifest-merger.jar"
110
111# Put the bug number in the target name so that false-positives have a hint in
112# the error message about why non-existent dependencies are there.
113build_config_target_suffix = "__build_config_crbug_908819"
114
115# Write the target's .build_config.json file. This is a json file that contains a
116# dictionary of information about how to build this target (things that
117# require knowledge about this target's dependencies and cannot be calculated
118# at gn-time). There is a special syntax to add a value in that dictionary to
119# an action/action_foreachs args:
120#   --python-arg=@FileArg($rebased_build_config_path:key0:key1)
121# At runtime, such an arg will be replaced by the value in the build_config.
122# See build/android/gyp/write_build_config.py and
123# build/android/gyp/util/build_utils.py:ExpandFileArgs
124template("write_build_config") {
125  action_with_pydeps(target_name) {
126    forward_variables_from(invoker, [ "testonly" ])
127    _type = invoker.type
128    _parent_invoker = invoker.invoker
129    _target_label =
130        get_label_info(":${_parent_invoker.target_name}", "label_no_toolchain")
131
132    # Ensure targets match naming patterns so that __assetres, __header, __host,
133    # and __validate targets work properly.
134    if (filter_exclude([ _type ], _java_resource_types) == []) {
135      if (filter_exclude([ _target_label ], java_resource_patterns) != []) {
136        assert(false, "Invalid java resource target name: $_target_label")
137      }
138    } else if (filter_exclude([ _type ], _java_library_types) == []) {
139      if (filter_exclude([ _target_label ], java_library_patterns) != [] ||
140          filter_exclude([ _target_label ], java_resource_patterns) == []) {
141        assert(false, "Invalid java library target name: $_target_label")
142      }
143    } else if (_type == "group") {
144      if (filter_exclude([ _target_label ], java_target_patterns) != []) {
145        assert(false, "Invalid java target name: $_target_label")
146      }
147    } else if (filter_exclude([ _type ], _java_leaf_types) != []) {
148      assert(false, "This java type needs a category: $_type")
149    }
150
151    if (defined(invoker.public_target_label)) {
152      _target_label = invoker.public_target_label
153    }
154
155    deps = []
156    if (defined(invoker.deps)) {
157      deps = invoker.deps
158    }
159    if (defined(invoker.android_manifest_dep)) {
160      deps += [ invoker.android_manifest_dep ]
161    }
162
163    script = "//build/android/gyp/write_build_config.py"
164    depfile = "$target_gen_dir/$target_name.d"
165    inputs = []
166    outputs = [ invoker.build_config ]
167
168    _deps_configs = []
169    if (defined(invoker.possible_config_deps)) {
170      foreach(_possible_dep, invoker.possible_config_deps) {
171        _dep_label = get_label_info(_possible_dep, "label_no_toolchain")
172        if (filter_exclude([ _dep_label ], java_target_patterns) == []) {
173          deps += [ "$_dep_label$build_config_target_suffix" ]
174          _dep_gen_dir = get_label_info(_possible_dep, "target_gen_dir")
175          _dep_name = get_label_info(_possible_dep, "name")
176          _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
177
178          _deps_configs += [ _dep_config ]
179        }
180      }
181    }
182    _public_deps_configs = []
183    if (defined(invoker.possible_config_public_deps)) {
184      foreach(_possible_dep, invoker.possible_config_public_deps) {
185        _dep_label = get_label_info(_possible_dep, "label_no_toolchain")
186
187        # E.g. Adding an action that generates a .java file that is then
188        # consumed by a subsequent java_library() target would not work
189        # because the libraries depend only on the nested targets of one
190        # another. It is simplest to just ban non-java public_deps.
191        assert(filter_exclude([ _dep_label ], java_target_patterns) == [],
192               "Only java_library targets can be used as public_deps. " +
193                   "Found:\n${_dep_label}\non Target:\n" +
194                   get_label_info(":$target_name", "label_no_toolchain"))
195
196        # Put the bug number in the target name so that false-positives
197        # have a hint in the error message about non-existent dependencies.
198        deps += [ "$_dep_label$build_config_target_suffix" ]
199        _dep_gen_dir = get_label_info(_possible_dep, "target_gen_dir")
200        _dep_name = get_label_info(_possible_dep, "name")
201        _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
202
203        _public_deps_configs += [ _dep_config ]
204      }
205    }
206    inputs += _deps_configs
207    inputs += _public_deps_configs
208    _rebased_deps_configs = rebase_path(_deps_configs, root_build_dir)
209    _rebased_public_deps_configs =
210        rebase_path(_public_deps_configs, root_build_dir)
211
212    args = [
213      "--type=$_type",
214      "--depfile",
215      rebase_path(depfile, root_build_dir),
216      "--deps-configs=$_rebased_deps_configs",
217      "--public-deps-configs=$_rebased_public_deps_configs",
218      "--build-config",
219      rebase_path(invoker.build_config, root_build_dir),
220      "--gn-target",
221      _target_label,
222    ]
223
224    if (defined(invoker.preferred_dep) && invoker.preferred_dep) {
225      args += [ "--preferred-dep" ]
226    }
227
228    if (defined(invoker.aar_path)) {
229      args += [
230        "--aar-path",
231        rebase_path(invoker.aar_path, root_build_dir),
232      ]
233    }
234
235    if (defined(invoker.chromium_code) && !invoker.chromium_code) {
236      # Default to chromium code if invoker did not pass anything.
237      args += [ "--non-chromium-code" ]
238    }
239
240    if (defined(invoker.device_jar_path)) {
241      args += [
242        "--device-jar-path",
243        rebase_path(invoker.device_jar_path, root_build_dir),
244      ]
245    }
246    if (defined(invoker.host_jar_path)) {
247      args += [
248        "--host-jar-path",
249        rebase_path(invoker.host_jar_path, root_build_dir),
250      ]
251    }
252    if (defined(invoker.unprocessed_jar_path)) {
253      args += [
254        "--unprocessed-jar-path",
255        rebase_path(invoker.unprocessed_jar_path, root_build_dir),
256      ]
257    }
258    if (defined(invoker.ijar_path)) {
259      args += [
260        "--interface-jar-path",
261        rebase_path(invoker.ijar_path, root_build_dir),
262      ]
263    }
264    if (defined(invoker.kotlinc_jar_path)) {
265      args += [
266        "--kotlinc-jar-path",
267        rebase_path(invoker.kotlinc_jar_path, root_build_dir),
268      ]
269    }
270    if (defined(invoker.java_resources_jar)) {
271      args += [
272        "--java-resources-jar-path",
273        rebase_path(invoker.java_resources_jar, root_build_dir),
274      ]
275    }
276    if (defined(invoker.annotation_processor_deps) &&
277        invoker.annotation_processor_deps != []) {
278      _processor_configs = []
279      foreach(_dep_label, invoker.annotation_processor_deps) {
280        deps += [ "$_dep_label$build_config_target_suffix" ]
281        _dep_gen_dir = get_label_info(_dep_label, "target_gen_dir")
282        _dep_name = get_label_info(_dep_label, "name")
283        _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
284        _processor_configs += [ _dep_config ]
285      }
286      _rebased_processor_configs =
287          rebase_path(_processor_configs, root_build_dir)
288      inputs += _processor_configs
289      args += [ "--annotation-processor-configs=$_rebased_processor_configs" ]
290    }
291
292    # Dex path for library targets, or the the intermediate library for apks.
293    if (defined(invoker.dex_path)) {
294      args += [
295        "--dex-path",
296        rebase_path(invoker.dex_path, root_build_dir),
297      ]
298    }
299
300    # Dex path for the final apk.
301    if (defined(invoker.final_dex_path)) {
302      args += [
303        "--final-dex-path",
304        rebase_path(invoker.final_dex_path, root_build_dir),
305      ]
306    }
307    if (defined(invoker.supports_android) && invoker.supports_android) {
308      args += [ "--supports-android" ]
309    }
310    if (defined(invoker.requires_android) && invoker.requires_android) {
311      args += [ "--requires-android" ]
312    }
313    if (defined(invoker.is_prebuilt) && invoker.is_prebuilt) {
314      args += [ "--is-prebuilt" ]
315    }
316    if (defined(invoker.bypass_platform_checks) &&
317        invoker.bypass_platform_checks) {
318      args += [ "--bypass-platform-checks" ]
319    }
320    if (defined(invoker.is_robolectric) && invoker.is_robolectric) {
321      args += [ "--is-robolectric" ]
322    }
323
324    if (defined(invoker.apk_under_test)) {
325      _dep_label = invoker.apk_under_test
326      _dep_gen_dir = get_label_info(_dep_label, "target_gen_dir")
327      _dep_name = get_label_info(_dep_label, "name")
328      _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
329      inputs += [ _dep_config ]
330      deps += [ "$_dep_label$build_config_target_suffix" ]
331      args += [
332        "--tested-apk-config",
333        rebase_path(_dep_config, root_build_dir),
334      ]
335    }
336
337    if (defined(invoker.asset_sources)) {
338      _rebased_asset_sources =
339          rebase_path(invoker.asset_sources, root_build_dir)
340      args += [ "--asset-sources=$_rebased_asset_sources" ]
341    }
342    if (defined(invoker.asset_renaming_sources)) {
343      _rebased_asset_renaming_sources =
344          rebase_path(invoker.asset_renaming_sources, root_build_dir)
345      args += [ "--asset-renaming-sources=$_rebased_asset_renaming_sources" ]
346
347      # These are zip paths, so no need to rebase.
348      args += [
349        "--asset-renaming-destinations=${invoker.asset_renaming_destinations}",
350      ]
351    }
352    if (defined(invoker.disable_compression) && invoker.disable_compression) {
353      args += [ "--disable-asset-compression" ]
354    }
355    if (defined(invoker.treat_as_locale_paks) && invoker.treat_as_locale_paks) {
356      args += [ "--treat-as-locale-paks" ]
357    }
358    if (defined(invoker.suffix_apk_assets_used_by)) {
359      _dep_label = invoker.suffix_apk_assets_used_by
360      _dep_gen_dir = get_label_info(_dep_label, "target_gen_dir")
361      _dep_name = get_label_info(_dep_label, "name")
362      _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
363      if (_dep_config != invoker.build_config) {
364        inputs += [ _dep_config ]
365        deps += [ "$_dep_label$build_config_target_suffix" ]
366      }
367      args += [
368        "--suffix-apk-assets-used-by",
369        rebase_path(_dep_config, root_build_dir),
370      ]
371    }
372
373    if (defined(invoker.merged_android_manifest)) {
374      args += [
375        "--merged-android-manifest",
376        rebase_path(invoker.merged_android_manifest, root_build_dir),
377      ]
378    }
379    if (defined(invoker.android_manifest)) {
380      inputs += [ invoker.android_manifest ]
381      args += [
382        "--android-manifest",
383        rebase_path(invoker.android_manifest, root_build_dir),
384      ]
385    }
386    if (defined(invoker.resources_zip)) {
387      args += [
388        "--resources-zip",
389        rebase_path(invoker.resources_zip, root_build_dir),
390      ]
391    }
392
393    if (defined(invoker.resource_overlay) && invoker.resource_overlay) {
394      args += [ "--resource-overlay" ]
395    }
396
397    if (defined(invoker.custom_package)) {
398      args += [
399        "--package-name",
400        invoker.custom_package,
401      ]
402    }
403    if (defined(invoker.r_text)) {
404      args += [
405        "--r-text-path",
406        rebase_path(invoker.r_text, root_build_dir),
407      ]
408    }
409    if (defined(invoker.res_size_info_path)) {
410      args += [
411        "--res-size-info",
412        rebase_path(invoker.res_size_info_path, root_build_dir),
413      ]
414    }
415    if (defined(invoker.res_sources_path)) {
416      _res_sources_path = rebase_path(invoker.res_sources_path, root_build_dir)
417      args += [ "--res-sources-path=$_res_sources_path" ]
418    }
419    if (defined(invoker.proto_resources_path)) {
420      _rebased_proto_resources =
421          rebase_path(invoker.proto_resources_path, root_build_dir)
422      args += [ "--apk-proto-resources=$_rebased_proto_resources" ]
423    }
424    if (defined(invoker.r_text_path)) {
425      _rebased_rtxt_path = rebase_path(invoker.r_text_path, root_build_dir)
426      args += [ "--r-text-path=$_rebased_rtxt_path" ]
427    }
428    if (defined(invoker.module_pathmap_path)) {
429      _rebased_pathmap_path =
430          rebase_path(invoker.module_pathmap_path, root_build_dir)
431      args += [ "--module-pathmap-path=$_rebased_pathmap_path" ]
432    }
433
434    if (defined(invoker.shared_libraries_runtime_deps_file)) {
435      # Don't list shared_libraries_runtime_deps_file as an input in order to
436      # avoid having to depend on the runtime_deps target. See comment in
437      # rules.gni for why we do this.
438      args += [
439        "--shared-libraries-runtime-deps",
440        rebase_path(invoker.shared_libraries_runtime_deps_file, root_build_dir),
441      ]
442    }
443
444    if (defined(invoker.base_allowlist_rtxt_path)) {
445      args += [
446        "--base-allowlist-rtxt-path",
447        rebase_path(invoker.base_allowlist_rtxt_path, root_build_dir),
448      ]
449    }
450
451    if (defined(invoker.loadable_modules)) {
452      _rebased_loadable_modules =
453          rebase_path(invoker.loadable_modules, root_build_dir)
454      args += [ "--loadable-modules=$_rebased_loadable_modules" ]
455    }
456
457    if (defined(invoker.secondary_abi_shared_libraries_runtime_deps_file)) {
458      # Don't list secondary_abi_shared_libraries_runtime_deps_file as an
459      # input in order to avoid having to depend on the runtime_deps target.
460      # See comment in rules.gni for why we do this.
461      args += [
462        "--secondary-abi-shared-libraries-runtime-deps",
463        rebase_path(invoker.secondary_abi_shared_libraries_runtime_deps_file,
464                    root_build_dir),
465      ]
466    }
467
468    if (defined(invoker.secondary_abi_loadable_modules) &&
469        invoker.secondary_abi_loadable_modules != []) {
470      _rebased_secondary_abi_loadable_modules =
471          rebase_path(invoker.secondary_abi_loadable_modules, root_build_dir)
472      args += [ "--secondary-abi-loadable-modules=$_rebased_secondary_abi_loadable_modules" ]
473    }
474
475    if (defined(invoker.native_lib_placeholders) &&
476        invoker.native_lib_placeholders != []) {
477      args += [ "--native-lib-placeholders=${invoker.native_lib_placeholders}" ]
478    }
479
480    if (defined(invoker.secondary_native_lib_placeholders) &&
481        invoker.secondary_native_lib_placeholders != []) {
482      args += [ "--secondary-native-lib-placeholders=${invoker.secondary_native_lib_placeholders}" ]
483    }
484
485    if (defined(invoker.library_always_compress)) {
486      args += [ "--library-always-compress=${invoker.library_always_compress}" ]
487    }
488
489    if (defined(invoker.apk_path)) {
490      # TODO(tiborg): Remove APK path from build config and use
491      # install_artifacts from metadata instead.
492      _rebased_apk_path = rebase_path(invoker.apk_path, root_build_dir)
493      args += [ "--apk-path=$_rebased_apk_path" ]
494      if (defined(invoker.incremental_apk_path)) {
495        _rebased_incremental_apk_path =
496            rebase_path(invoker.incremental_apk_path, root_build_dir)
497        _rebased_incremental_install_json_path =
498            rebase_path(invoker.incremental_install_json_path, root_build_dir)
499        args += [
500          "--incremental-install-json-path=$_rebased_incremental_install_json_path",
501          "--incremental-apk-path=$_rebased_incremental_apk_path",
502        ]
503      }
504    }
505
506    if (defined(invoker.target_sources_file)) {
507      args += [
508        "--target-sources-file",
509        rebase_path(invoker.target_sources_file, root_build_dir),
510      ]
511    }
512    if (defined(invoker.srcjar)) {
513      args += [
514        "--srcjar",
515        rebase_path(invoker.srcjar, root_build_dir),
516      ]
517    }
518    if (defined(invoker.bundled_srcjars)) {
519      _rebased_bundled_srcjars =
520          rebase_path(invoker.bundled_srcjars, root_build_dir)
521      args += [ "--bundled-srcjars=$_rebased_bundled_srcjars" ]
522    }
523    if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) {
524      args += [ "--proguard-enabled" ]
525    }
526    if (defined(invoker.proguard_mapping_path)) {
527      _rebased_proguard_mapping_path =
528          rebase_path(invoker.proguard_mapping_path, root_build_dir)
529      args += [ "--proguard-mapping-path=$_rebased_proguard_mapping_path" ]
530    }
531    if (defined(invoker.input_jars_paths)) {
532      _rebased_input_jars_paths =
533          rebase_path(invoker.input_jars_paths, root_build_dir)
534      args += [ "--extra-classpath-jars=$_rebased_input_jars_paths" ]
535    }
536    if (defined(invoker.low_classpath_priority) &&
537        invoker.low_classpath_priority) {
538      args += [ "--low-classpath-priority" ]
539    }
540    if (defined(invoker.mergeable_android_manifests)) {
541      _rebased_mergeable_android_manifests =
542          rebase_path(invoker.mergeable_android_manifests, root_build_dir)
543      args += [
544        "--mergeable-android-manifests=$_rebased_mergeable_android_manifests",
545      ]
546    }
547    if (defined(invoker.proguard_configs)) {
548      _rebased_proguard_configs =
549          rebase_path(invoker.proguard_configs, root_build_dir)
550      args += [ "--proguard-configs=$_rebased_proguard_configs" ]
551    }
552    if (defined(invoker.gradle_treat_as_prebuilt) &&
553        invoker.gradle_treat_as_prebuilt) {
554      args += [ "--gradle-treat-as-prebuilt" ]
555    }
556    if (defined(invoker.main_class)) {
557      args += [
558        "--main-class",
559        invoker.main_class,
560      ]
561    }
562    if (defined(invoker.direct_deps_only) && invoker.direct_deps_only) {
563      args += [ "--direct-deps-only" ]
564    }
565    if (defined(invoker.use_interface_jars) && invoker.use_interface_jars) {
566      args += [ "--use-interface-jars" ]
567    }
568    if (defined(invoker.base_module_target)) {
569      _dep_label = invoker.base_module_target
570      _dep_gen_dir = get_label_info(_dep_label, "target_gen_dir")
571      _dep_name = get_label_info(_dep_label, "name")
572      _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
573      deps += [ "$_dep_label$build_config_target_suffix" ]
574      inputs += [ _dep_config ]
575      args += [
576        "--base-module-build-config",
577        rebase_path(_dep_config, root_build_dir),
578      ]
579    }
580    if (defined(invoker.parent_module_target)) {
581      _dep_label = invoker.parent_module_target
582      _dep_gen_dir = get_label_info(_dep_label, "target_gen_dir")
583      _dep_name = get_label_info(_dep_label, "name")
584      _dep_config = "$_dep_gen_dir/$_dep_name.build_config.json"
585      deps += [ "$_dep_label$build_config_target_suffix" ]
586      inputs += [ _dep_config ]
587      args += [
588        "--parent-module-build-config",
589        rebase_path(_dep_config, root_build_dir),
590      ]
591    }
592    if (defined(invoker.module_name)) {
593      args += [
594        "--module-name",
595        invoker.module_name,
596      ]
597    }
598    if (defined(invoker.modules)) {
599      foreach(_module, invoker.modules) {
600        if (defined(_module.uses_split)) {
601          args += [ "--uses-split=${_module.name}:${_module.uses_split}" ]
602        }
603      }
604    }
605    if (defined(invoker.module_build_configs)) {
606      inputs += invoker.module_build_configs
607      _rebased_configs =
608          rebase_path(invoker.module_build_configs, root_build_dir)
609      args += [ "--module-build-configs=$_rebased_configs" ]
610    }
611    if (defined(invoker.add_view_trace_events) &&
612        invoker.add_view_trace_events) {
613      # Adding trace events involves rewriting bytecode and generating a new set
614      # of jar files. In order to avoid conflicts between bundles we save the
615      # new jars in a bundle specific gen/ directory. The build config for the
616      # bundle, and each one of its modules need a path to a bundle specific
617      # gen/ directory in order to generate a list of rewritten jar paths.
618      # We use the base module's target_gen_dir because non-base modules and the
619      # app bundle targets have a reference to it (base_module_target).
620      if (_type == "android_app_bundle") {
621        _trace_events_target_name =
622            get_label_info(_parent_invoker.base_module_target, "name")
623      } else if (defined(invoker.base_module_target)) {
624        _trace_events_target_name =
625            get_label_info(invoker.base_module_target, "name")
626      } else {
627        _grandparent_invoker = _parent_invoker.invoker
628        _trace_events_target_name = _grandparent_invoker.target_name
629      }
630
631      # FIXME: This should likely be using the base module's target_out_dir
632      #     rather than the current target's.
633      args += [
634        "--trace-events-jar-dir",
635        rebase_path("$target_out_dir/$_trace_events_target_name",
636                    root_build_dir),
637      ]
638    }
639    if (defined(invoker.version_name)) {
640      args += [
641        "--version-name",
642        invoker.version_name,
643      ]
644    }
645    if (defined(invoker.version_code)) {
646      args += [
647        "--version-code",
648        invoker.version_code,
649      ]
650    }
651    if (defined(invoker.recursive_resource_deps) &&
652        invoker.recursive_resource_deps) {
653      args += [ "--recursive-resource-deps" ]
654    }
655    if (current_toolchain != default_toolchain) {
656      # This has to be a built-time error rather than a GN assert because many
657      # packages have a mix of java and non-java targets. For example, the
658      # following would fail even though nothing depends on :bar(//baz):
659      #
660      # shared_library("foo") {
661      # }
662      #
663      # android_library("bar") {
664      #   deps = [ ":foo(//baz)" ]
665      #   assert(current_toolchain == default_toolchain)
666      # }
667      _msg = [
668        "Tried to build an Android target in a non-default toolchain.",
669        "target: $_target_label",
670        "current_toolchain: $current_toolchain",
671        "default_toolchain: $default_toolchain",
672      ]
673      args += [ "--fail=$_msg" ]
674    }
675  }
676}
677
678template("generate_android_wrapper") {
679  generate_wrapper(target_name) {
680    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
681    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
682    generator_script = "//build/android/gyp/generate_android_wrapper.py"
683    sources = [
684      "//build/android/gyp/util/build_utils.py",
685      "//build/gn_helpers.py",
686      "//build/util/generate_wrapper.py",
687    ]
688  }
689}
690
691template("generate_r_java") {
692  action_with_pydeps(target_name) {
693    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
694    depfile = "$target_gen_dir/${invoker.target_name}.d"
695    inputs = [ invoker.build_config ]
696    outputs = [ invoker.srcjar_path ]
697    _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
698    script = "//build/android/gyp/create_r_java.py"
699    args = [
700      "--depfile",
701      rebase_path(depfile, root_build_dir),
702      "--srcjar-out",
703      rebase_path(invoker.srcjar_path, root_build_dir),
704      "--deps-rtxts=@FileArg($_rebased_build_config:deps_info:dependency_r_txt_files)",
705      "--r-package=${invoker.package}",
706    ]
707  }
708}
709
710# Generates a script in the build bin directory which runs the test
711# target using the test runner script in build/android/test_runner.py.
712template("test_runner_script") {
713  testonly = true
714  _test_name = invoker.test_name
715  _test_type = invoker.test_type
716  _is_unit_test = defined(invoker.is_unit_test) && invoker.is_unit_test
717  _incremental_apk = defined(invoker.incremental_apk) && invoker.incremental_apk
718
719  _runtime_deps =
720      !defined(invoker.ignore_all_data_deps) || !invoker.ignore_all_data_deps
721
722  if (_runtime_deps) {
723    # This runtime_deps file is used at runtime and thus cannot go in
724    # target_gen_dir.
725    _target_dir_name = get_label_info(":$target_name", "dir")
726    _runtime_deps_file =
727        "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.runtime_deps"
728    _runtime_deps_target = "${target_name}__write_deps"
729    group(_runtime_deps_target) {
730      forward_variables_from(invoker,
731                             [
732                               "data",
733                               "deps",
734                               "public_deps",
735                             ])
736      data_deps = []
737      if (defined(invoker.apk_target)) {
738        data_deps += [ invoker.apk_target ]
739      }
740      if (defined(invoker.data_deps)) {
741        data_deps += invoker.data_deps
742      }
743      if (defined(invoker.apk_under_test)) {
744        data_deps += [ invoker.apk_under_test ]
745      }
746      if (defined(invoker.additional_apks)) {
747        data_deps += invoker.additional_apks
748      }
749      if (defined(invoker.data_deps)) {
750        data_deps += invoker.data_deps
751      }
752      write_runtime_deps = _runtime_deps_file
753    }
754  }
755
756  if (defined(invoker.apk_under_test)) {
757    _install_artifacts_json =
758        "${target_gen_dir}/${target_name}.install_artifacts"
759    _install_artifacts_target_name = "${target_name}__install_artifacts"
760    generated_file(_install_artifacts_target_name) {
761      deps = [ invoker.apk_under_test ]
762      output_conversion = "json"
763      outputs = [ _install_artifacts_json ]
764      data_keys = [ "install_artifacts" ]
765      walk_keys = [ "install_artifacts_barrier" ]
766      rebase = root_build_dir
767    }
768  }
769
770  generate_android_wrapper(target_name) {
771    forward_variables_from(invoker,
772                           [
773                             "assert_no_deps",
774                             "metadata",
775                             "public_deps",
776                             "visibility",
777                           ])
778    wrapper_script = "$root_build_dir/bin/run_${_test_name}"
779
780    executable = "//testing/test_env.py"
781
782    if (defined(invoker.android_test_runner_script)) {
783      _runner_script = invoker.android_test_runner_script
784    } else {
785      _runner_script = "//build/android/test_runner.py"
786    }
787
788    deps = []
789    if (defined(invoker.deps)) {
790      deps = invoker.deps
791    }
792    data_deps = [
793      "//build/android:test_runner_core_py",
794      "//testing:test_scripts_shared",
795    ]
796    if (_test_type != "junit") {
797      data_deps += [ "//build/android:test_runner_device_support" ]
798    }
799    if (defined(invoker.data_deps)) {
800      data_deps += invoker.data_deps
801    }
802    data = []
803    if (defined(invoker.data)) {
804      data += invoker.data
805    }
806
807    executable_args = [
808      "@WrappedPath(" + rebase_path(_runner_script, root_build_dir) + ")",
809      _test_type,
810      "--output-directory",
811      "@WrappedPath(.)",
812      "--wrapper-script-args",
813    ]
814
815    if (_is_unit_test) {
816      executable_args += [ "--is-unit-test" ]
817    }
818
819    if (_runtime_deps) {
820      deps += [ ":$_runtime_deps_target" ]
821      data += [ _runtime_deps_file ]
822      _rebased_runtime_deps_file =
823          rebase_path(_runtime_deps_file, root_build_dir)
824      executable_args += [
825        "--runtime-deps-path",
826        "@WrappedPath(${_rebased_runtime_deps_file})",
827      ]
828    }
829
830    # apk_target is not used for native executable tests
831    # (e.g. breakpad_unittests).
832    if (defined(invoker.apk_target)) {
833      assert(!defined(invoker.executable_dist_dir))
834      deps += [ "${invoker.apk_target}$build_config_target_suffix" ]
835      _apk_build_config =
836          get_label_info(invoker.apk_target, "target_gen_dir") + "/" +
837          get_label_info(invoker.apk_target, "name") + ".build_config.json"
838      _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir)
839      not_needed([ "_rebased_apk_build_config" ])
840    } else if (_test_type == "gtest") {
841      assert(
842          defined(invoker.executable_dist_dir),
843          "Must define either apk_target or executable_dist_dir for test_runner_script()")
844      _rebased_executable_dist_dir =
845          rebase_path(invoker.executable_dist_dir, root_build_dir)
846      executable_args += [
847        "--executable-dist-dir",
848        "@WrappedPath(${_rebased_executable_dist_dir})",
849      ]
850    }
851
852    if (use_jacoco_coverage) {
853      # Keep in sync with recipe constant for recipe to find coverage data
854      # files from local java tests: https://bit.ly/3Zul6do
855      _jacoco_coverage_dir_name = "java_coverage"
856    }
857
858    _device_test = true
859    if (_test_type == "gtest") {
860      assert(defined(invoker.test_suite))
861      executable_args += [
862        "--suite",
863        invoker.test_suite,
864      ]
865      if (use_clang_coverage) {
866        # Set a default coverage output directory (can be overridden by user
867        # passing the same flag).
868        _rebased_coverage_dir =
869            rebase_path("$root_out_dir/coverage", root_build_dir)
870        executable_args += [
871          "--coverage-dir",
872          "@WrappedPath(${_rebased_coverage_dir})",
873        ]
874      }
875    } else if (_test_type == "instrumentation") {
876      _test_apk = "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:apk_path))"
877      if (_incremental_apk) {
878        _test_apk = "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:incremental_apk_path))"
879      }
880      executable_args += [
881        "--test-apk",
882        _test_apk,
883      ]
884      if (defined(invoker.apk_under_test)) {
885        if (_incremental_apk) {
886          deps += [ "${invoker.apk_under_test}$build_config_target_suffix" ]
887          _apk_under_test_build_config =
888              get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" +
889              get_label_info(invoker.apk_under_test, "name") +
890              ".build_config.json"
891          _rebased_apk_under_test_build_config =
892              rebase_path(_apk_under_test_build_config, root_build_dir)
893          _apk_under_test = "@WrappedPath(@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path))"
894        } else {
895          deps += [ ":${_install_artifacts_target_name}" ]
896          _rebased_install_artifacts_json =
897              rebase_path(_install_artifacts_json, root_build_dir)
898          _apk_under_test =
899              "@WrappedPath(@FileArg($_rebased_install_artifacts_json[]))"
900        }
901        executable_args += [
902          "--apk-under-test",
903          _apk_under_test,
904        ]
905      }
906      if (defined(invoker.use_webview_provider)) {
907        deps += [ "${invoker.use_webview_provider}$build_config_target_suffix" ]
908        _build_config =
909            get_label_info(invoker.use_webview_provider, "target_gen_dir") +
910            "/" + get_label_info(invoker.use_webview_provider, "name") +
911            ".build_config.json"
912        _rebased_build_config = rebase_path(_build_config, root_build_dir)
913        executable_args += [
914          "--use-webview-provider",
915          "@WrappedPath(@FileArg($_rebased_build_config:deps_info:apk_path))",
916        ]
917      }
918      if (defined(invoker.proguard_mapping_path)) {
919        if (_incremental_apk) {
920          not_needed(invoker, [ "proguard_mapping_path" ])
921        } else {
922          data += [ invoker.proguard_mapping_path ]
923          _rebased_mapping_path =
924              rebase_path(invoker.proguard_mapping_path, root_build_dir)
925          executable_args += [
926            "--proguard-mapping-path",
927            "@WrappedPath($_rebased_mapping_path)",
928          ]
929        }
930      }
931      if (use_jacoco_coverage) {
932        # Set a default coverage output directory (can be overridden by user
933        # passing the same flag).
934        _rebased_coverage_dir =
935            rebase_path("$root_out_dir/$_jacoco_coverage_dir_name",
936                        root_build_dir)
937        executable_args += [
938          "--coverage-dir",
939          "@WrappedPath(${_rebased_coverage_dir})",
940        ]
941      }
942    } else if (_test_type == "junit") {
943      assert(defined(invoker.test_suite))
944      _device_test = false
945      executable_args += [
946        "--test-suite",
947        invoker.test_suite,
948        "--native-libs-dir",
949        "@WrappedPath($_robolectric_libs_dir)",
950      ]
951
952      # Test runner uses this generated wrapper script.
953      data += [ "$root_build_dir/bin/helper/${invoker.test_suite}" ]
954
955      deps += [ ":${invoker.test_suite}$build_config_target_suffix" ]
956
957      _rebased_robolectric_runtime_deps_dir =
958          rebase_path("//third_party/robolectric/cipd/lib", root_build_dir)
959      _rebased_resource_apk = rebase_path(invoker.resource_apk, root_build_dir)
960      executable_args += [
961        "--resource-apk",
962        "@WrappedPath(${_rebased_resource_apk})",
963        "--robolectric-runtime-deps-dir",
964        "@WrappedPath(${_rebased_robolectric_runtime_deps_dir})",
965      ]
966      if (build_with_chromium) {
967        _allowlist = "//testing/android/junit/shadows-allowlist.txt"
968        data += [ _allowlist ]
969        _rebased_allowlist = rebase_path(_allowlist, root_build_dir)
970        executable_args += [
971          "--shadows-allowlist",
972          "@WrappedPath($_rebased_allowlist)",
973        ]
974      }
975      if (use_jacoco_coverage) {
976        # Set a default coverage output directory (can be overridden by user
977        # passing the same flag).
978        _rebased_coverage_dir =
979            rebase_path("$root_out_dir/$_jacoco_coverage_dir_name",
980                        root_build_dir)
981        executable_args += [
982          "--coverage-dir",
983          "@WrappedPath(${_rebased_coverage_dir})",
984        ]
985      }
986    } else if (_test_type == "linker") {
987      executable_args += [
988        "--test-apk",
989        "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:apk_path))",
990      ]
991    } else {
992      assert(false, "Invalid test type: $_test_type.")
993    }
994
995    # Devil does not reliably work with component builds of its tools.
996    # There's no benefit to them, so fall back to prebuilts for component builds.
997    # https://crbug.com/1404180
998    if (_test_type != "junit" && !is_component_build) {
999      executable_args += [ "--use-local-devil-tools" ]
1000    }
1001
1002    if (defined(invoker.additional_apks)) {
1003      foreach(additional_apk, invoker.additional_apks) {
1004        deps += [ "$additional_apk$build_config_target_suffix" ]
1005        _build_config =
1006            get_label_info(additional_apk, "target_gen_dir") + "/" +
1007            get_label_info(additional_apk, "name") + ".build_config.json"
1008        _rebased_build_config = rebase_path(_build_config, root_build_dir)
1009        executable_args += [
1010          "--additional-apk",
1011          "@WrappedPath(@FileArg($_rebased_build_config:deps_info:apk_path))",
1012        ]
1013      }
1014    }
1015    if (defined(invoker.shard_timeout)) {
1016      executable_args += [ "--shard-timeout=${invoker.shard_timeout}" ]
1017    }
1018    if (_incremental_apk) {
1019      executable_args += [
1020        "--test-apk-incremental-install-json",
1021        "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:incremental_install_json_path))",
1022      ]
1023      if (defined(invoker.apk_under_test)) {
1024        executable_args += [
1025          "--apk-under-test-incremental-install-json",
1026          "@WrappedPath(@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_install_json_path))",
1027        ]
1028      }
1029      executable_args += [ "--fast-local-dev" ]
1030    }
1031    if (_device_test && is_asan) {
1032      executable_args += [ "--timeout-scale=4" ]
1033    }
1034
1035    if (defined(invoker.modules)) {
1036      foreach(module, invoker.modules) {
1037        executable_args += [
1038          "--module",
1039          module,
1040        ]
1041      }
1042    }
1043
1044    if (defined(invoker.fake_modules)) {
1045      foreach(fake_module, invoker.fake_modules) {
1046        executable_args += [
1047          "--fake-module",
1048          fake_module,
1049        ]
1050      }
1051    }
1052
1053    if (defined(invoker.additional_locales)) {
1054      foreach(locale, invoker.additional_locales) {
1055        executable_args += [
1056          "--additional-locale",
1057          locale,
1058        ]
1059      }
1060    }
1061
1062    if (defined(invoker.extra_args)) {
1063      executable_args += invoker.extra_args
1064    }
1065  }
1066}
1067
1068if (enable_java_templates) {
1069  template("android_lint") {
1070    action_with_pydeps(target_name) {
1071      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1072
1073      # https://crbug.com/1098752 Fix for bot OOM (https://crbug.com/1098333).
1074      if (defined(java_cmd_pool_size)) {
1075        pool = "//build/config/android:java_cmd_pool($default_toolchain)"
1076      } else {
1077        pool = "//build/toolchain:link_pool($default_toolchain)"
1078      }
1079
1080      # Lint requires generated sources and generated resources from the build.
1081      # Turbine __header targets depend on all generated sources, and the
1082      # __assetres targets depend on all generated resources.
1083      deps = []
1084      if (defined(invoker.deps)) {
1085        _lib_deps =
1086            filter_exclude(filter_include(invoker.deps, java_library_patterns),
1087                           java_resource_patterns)
1088        foreach(_lib_dep, _lib_deps) {
1089          # Expand //foo/java -> //foo/java:java
1090          _lib_dep = get_label_info(_lib_dep, "label_no_toolchain")
1091          deps += [
1092            "${_lib_dep}__assetres",
1093            "${_lib_dep}__header",
1094          ]
1095        }
1096
1097        # Keep non-java deps as they may generate files used only by lint.
1098        # e.g. generated suppressions.xml files.
1099        deps += filter_exclude(invoker.deps, _lib_deps)
1100      }
1101
1102      if (defined(invoker.min_sdk_version)) {
1103        _min_sdk_version = invoker.min_sdk_version
1104      } else {
1105        _min_sdk_version = default_min_sdk_version
1106      }
1107
1108      if (defined(invoker.lint_jar_path)) {
1109        _lint_jar_path = invoker.lint_jar_path
1110      } else {
1111        _lint_jar_path = _default_lint_jar_path
1112      }
1113
1114      # It is not safe to run two lint versions concurrently since they will
1115      # wipe the cache on version mismatch. When using a non-default lint
1116      # version, make each target use their own cache directory.
1117      _use_custom_cache_dir = _lint_jar_path != _default_lint_jar_path
1118
1119      # Save generated xml files in a consistent location for debugging.
1120      if (defined(invoker.lint_gen_dir)) {
1121        _lint_gen_dir = invoker.lint_gen_dir
1122      } else {
1123        _lint_gen_dir = "$target_gen_dir/$target_name"
1124      }
1125      _backported_methods = "//third_party/r8/backported_methods.txt"
1126
1127      script = "//build/android/gyp/lint.py"
1128      depfile = "$target_gen_dir/$target_name.d"
1129      inputs = java_paths_for_inputs + [
1130                 _lint_jar_path,
1131                 _custom_lint_jar_path,
1132                 _backported_methods,
1133               ]
1134
1135      args = [
1136        "--target-name",
1137        get_label_info(":${target_name}", "label_no_toolchain"),
1138        "--depfile",
1139        rebase_path(depfile, root_build_dir),
1140        "--lint-jar-path",
1141        rebase_path(_lint_jar_path, root_build_dir),
1142        "--custom-lint-jar-path",
1143        rebase_path(_custom_lint_jar_path, root_build_dir),
1144        "--lint-gen-dir",
1145        rebase_path(_lint_gen_dir, root_build_dir),
1146        "--android-sdk-version=${lint_android_sdk_version}",
1147        "--min-sdk-version=$_min_sdk_version",
1148        "--android-sdk-root",
1149        rebase_path(lint_android_sdk_root, root_build_dir),
1150        "--backported-methods",
1151        rebase_path(_backported_methods, root_build_dir),
1152      ]
1153
1154      if (!_use_custom_cache_dir) {
1155        _cache_dir = "$root_build_dir/android_lint_cache"
1156        _create_cache_stamp_path = "$_cache_dir/build.lint.stamp"
1157
1158        # By default, lint.py will use "$_lint_gen_dir/cache".
1159        args += [
1160          "--cache-dir",
1161          rebase_path(_cache_dir, root_build_dir),
1162        ]
1163      }
1164
1165      if (defined(invoker.skip_build_server) && invoker.skip_build_server) {
1166        # Nocompile tests need lint to fail through ninja.
1167        args += [ "--skip-build-server" ]
1168      } else if (android_static_analysis == "build_server") {
1169        args += [ "--use-build-server" ]
1170      }
1171
1172      if (defined(invoker.lint_suppressions_file)) {
1173        inputs += [ invoker.lint_suppressions_file ]
1174
1175        args += [
1176          "--config-path",
1177          rebase_path(invoker.lint_suppressions_file, root_build_dir),
1178        ]
1179      }
1180
1181      if (defined(invoker.manifest_package)) {
1182        args += [ "--manifest-package=${invoker.manifest_package}" ]
1183      }
1184
1185      if (treat_warnings_as_errors) {
1186        args += [ "--warnings-as-errors" ]
1187      }
1188
1189      if (defined(invoker.lint_baseline_file)) {
1190        if (compute_inputs_for_analyze) {
1191          # The baseline file is included in lint.py as a depfile dep. Since
1192          # removing it regenerates the file, it is useful to not have this as
1193          # a gn input during local development. Add it only for bots' analyze.
1194          inputs += [ invoker.lint_baseline_file ]
1195        }
1196        args += [
1197          # Baseline allows us to turn on lint warnings without fixing all the
1198          # pre-existing issues. This stops the flood of new issues while the
1199          # existing ones are being fixed.
1200          "--baseline",
1201          rebase_path(invoker.lint_baseline_file, root_build_dir),
1202        ]
1203      }
1204
1205      if (defined(invoker.create_cache) && invoker.create_cache) {
1206        # Putting the stamp file in the cache dir allows us to depend on ninja
1207        # to create the cache dir for us.
1208        args += [ "--create-cache" ]
1209        _stamp_path = _create_cache_stamp_path
1210      } else {
1211        _stamp_path = "$target_out_dir/$target_name/build.lint.stamp"
1212        deps += [ invoker.build_config_dep ]
1213        if (!_use_custom_cache_dir) {
1214          deps += [ "//build/android:prepare_android_lint_cache" ]
1215          inputs += [ _create_cache_stamp_path ]
1216        }
1217        inputs += [ invoker.build_config ]
1218        _rebased_build_config =
1219            rebase_path(invoker.build_config, root_build_dir)
1220
1221        args += [
1222          "--manifest-path=@FileArg($_rebased_build_config:deps_info:lint_android_manifest)",
1223          "--extra-manifest-paths=@FileArg($_rebased_build_config:deps_info:lint_extra_android_manifests)",
1224
1225          # Lint requires all source and all resource files to be passed in the
1226          # same invocation for checks like UnusedResources.
1227          "--sources=@FileArg($_rebased_build_config:deps_info:lint_sources)",
1228          "--aars=@FileArg($_rebased_build_config:deps_info:lint_aars)",
1229          "--srcjars=@FileArg($_rebased_build_config:deps_info:lint_srcjars)",
1230          "--resource-sources=@FileArg($_rebased_build_config:deps_info:lint_resource_sources)",
1231          "--resource-zips=@FileArg($_rebased_build_config:deps_info:lint_resource_zips)",
1232
1233          # The full classpath is required for annotation checks like @IntDef.
1234          "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)",
1235        ]
1236      }
1237
1238      outputs = [ _stamp_path ]
1239      args += [
1240        "--stamp",
1241        rebase_path(_stamp_path, root_build_dir),
1242      ]
1243    }
1244  }
1245
1246  template("trace_references") {
1247    action_with_pydeps(target_name) {
1248      forward_variables_from(invoker,
1249                             TESTONLY_AND_VISIBILITY + [ "public_deps" ])
1250      script = "//build/android/gyp/tracereferences.py"
1251      inputs = java_paths_for_inputs + [
1252                 _r8_path,
1253                 invoker.tracerefs_json,
1254               ]
1255      depfile = "$target_gen_dir/$target_name.d"
1256      outputs = [ "$target_out_dir/$target_name.tracereferences.stamp" ]
1257      args = [
1258        "--depfile",
1259        rebase_path(depfile, root_build_dir),
1260        "--tracerefs-json",
1261        rebase_path(invoker.tracerefs_json, root_build_dir),
1262        "--stamp",
1263        rebase_path(outputs[0], root_build_dir),
1264      ]
1265      if (android_static_analysis == "build_server") {
1266        args += [ "--use-build-server" ]
1267      }
1268      if (treat_warnings_as_errors) {
1269        args += [ "--warnings-as-errors" ]
1270      }
1271    }
1272  }
1273
1274  template("proguard") {
1275    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1276    _script = "//build/android/gyp/proguard.py"
1277    _deps = invoker.deps
1278
1279    _inputs = java_paths_for_inputs + [
1280                invoker.build_config,
1281                _r8_path,
1282                _custom_r8_path,
1283              ]
1284    if (defined(invoker.inputs)) {
1285      _inputs += invoker.inputs
1286    }
1287    if (defined(invoker.proguard_mapping_path)) {
1288      _mapping_path = invoker.proguard_mapping_path
1289    } else {
1290      _mapping_path = "${invoker.output}.mapping"
1291    }
1292
1293    _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
1294
1295    # This is generally the apk name, and serves to identify the mapping
1296    # file that would be required to deobfuscate a stacktrace.
1297    _mapping_basename = get_path_info(_mapping_path, "name")
1298    _version_code = "@FileArg($_rebased_build_config:deps_info:version_code)"
1299    _package_name = "@FileArg($_rebased_build_config:deps_info:package_name)"
1300    if (defined(invoker.package_name)) {
1301      _package_name = invoker.package_name
1302    }
1303    if (defined(invoker.version_code)) {
1304      _version_code = invoker.version_code
1305    }
1306
1307    # The Mapping ID is parsed to when uploading mapping files.
1308    # See: https://crbug.com/1417308
1309    _source_file_template =
1310        "chromium-$_mapping_basename-$android_channel-$_version_code"
1311
1312    _args = [
1313      "--min-api=${invoker.min_sdk_version}",
1314      "--mapping-output",
1315      rebase_path(_mapping_path, root_build_dir),
1316      "--sdk-jars",
1317      "@FileArg($_rebased_build_config:android:sdk_jars)",
1318      "--sdk-extension-jars",
1319      "@FileArg($_rebased_build_config:deps_info:proguard_classpath_jars)",
1320      "--r8-path",
1321      rebase_path(_r8_path, root_build_dir),
1322      "--custom-r8-path",
1323      rebase_path(_custom_r8_path, root_build_dir),
1324      "--package-name=$_package_name",
1325      "--source-file",
1326      _source_file_template,
1327      "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)",
1328    ]
1329    if (treat_warnings_as_errors) {
1330      _args += [ "--warnings-as-errors" ]
1331    }
1332
1333    if ((!defined(invoker.proguard_enable_obfuscation) ||
1334         invoker.proguard_enable_obfuscation) && enable_proguard_obfuscation) {
1335      _args += [ "--enable-obfuscation" ]
1336    }
1337    if (defined(invoker.repackage_classes)) {
1338      _args += [ "--repackage-classes=" + invoker.repackage_classes ]
1339    }
1340    if (defined(invoker.apply_mapping)) {
1341      _inputs += [ invoker.apply_mapping ]
1342      _rebased_apply_mapping_path =
1343          rebase_path(invoker.apply_mapping, root_build_dir)
1344      args += [ "--apply-mapping=$_rebased_apply_mapping_path" ]
1345    }
1346
1347    if (defined(invoker.proguard_configs)) {
1348      _inputs += invoker.proguard_configs
1349      _rebased_proguard_configs =
1350          rebase_path(invoker.proguard_configs, root_build_dir)
1351      _args += [ "--proguard-configs=$_rebased_proguard_configs" ]
1352    }
1353
1354    if (defined(invoker.modules)) {
1355      foreach(_feature_module, invoker.modules) {
1356        _rebased_module_build_config =
1357            rebase_path(_feature_module.build_config, root_build_dir)
1358        _args += [
1359          "--feature-name=${_feature_module.name}",
1360          "--dex-dest=@FileArg($_rebased_module_build_config:final_dex:path)",
1361        ]
1362
1363        # The bundle's build config has the correct classpaths - the individual
1364        # modules' build configs may double-use some jars.
1365        if (defined(invoker.add_view_trace_events) &&
1366            invoker.add_view_trace_events) {
1367          _args += [ "--feature-jars=@FileArg($_rebased_build_config:modules:${_feature_module.name}:trace_event_rewritten_device_classpath)" ]
1368        } else {
1369          _args += [ "--feature-jars=@FileArg($_rebased_build_config:modules:${_feature_module.name}:device_classpath)" ]
1370        }
1371
1372        if (defined(_feature_module.uses_split)) {
1373          _args += [ "--uses-split=${_feature_module.name}:${_feature_module.uses_split}" ]
1374        }
1375        _deps += [ _feature_module.build_config_target ]
1376      }
1377      _stamp = "${target_gen_dir}/${target_name}.r8.stamp"
1378      _outputs = [ _stamp ]
1379      _output_arg = [
1380        "--stamp",
1381        rebase_path(_stamp, root_build_dir),
1382      ]
1383    } else {
1384      if (defined(invoker.has_apk_under_test) && invoker.has_apk_under_test) {
1385        _args += [ "--input-paths=@FileArg($_rebased_build_config:deps_info:device_classpath_extended)" ]
1386      } else {
1387        _args += [ "--input-paths=@FileArg($_rebased_build_config:deps_info:device_classpath)" ]
1388      }
1389
1390      # We don't directly set the output arg on the _args variable since it is
1391      # shared with the expectation target that uses its own stamp file and
1392      # does not take an --output-path.
1393      _output_arg = [
1394        "--output-path",
1395        rebase_path(invoker.output, root_build_dir),
1396      ]
1397      _outputs = [ invoker.output ]
1398    }
1399    _outputs += [ _mapping_path ]
1400
1401    _enable_checks = !defined(invoker.enable_proguard_checks) ||
1402                     invoker.enable_proguard_checks
1403    if (!_enable_checks) {
1404      _args += [ "--disable-checks" ]
1405    }
1406
1407    _ignore_desugar_missing_deps =
1408        defined(invoker.ignore_desugar_missing_deps) &&
1409        invoker.ignore_desugar_missing_deps
1410    if (!_ignore_desugar_missing_deps) {
1411      _args += [ "--show-desugar-default-interface-warnings" ]
1412    }
1413
1414    if (defined(invoker.custom_assertion_handler)) {
1415      _args += [
1416        "--assertion-handler",
1417        invoker.custom_assertion_handler,
1418      ]
1419    } else if (enable_java_asserts) {
1420      # The default for generating dex file format is
1421      # --force-disable-assertions.
1422      _args += [ "--force-enable-assertions" ]
1423    }
1424
1425    if (defined(invoker.proguard_args)) {
1426      _args += invoker.proguard_args
1427    }
1428
1429    if (defined(invoker.expected_proguard_config)) {
1430      _expectations_target =
1431          "${invoker.top_target_name}_validate_proguard_config"
1432      action_with_pydeps(_expectations_target) {
1433        script = _script
1434
1435        # Need to depend on all deps so that proguard.txt within .aar files get
1436        # extracted.
1437        deps = _deps
1438        depfile = "${target_gen_dir}/${target_name}.d"
1439        inputs = [
1440          invoker.build_config,
1441          invoker.expected_proguard_config,
1442        ]
1443        _actual_file = "$target_gen_dir/$target_name.proguard_configs"
1444        _failure_file =
1445            "$expectations_failure_dir/" +
1446            string_replace(invoker.expected_proguard_config, "/", "_")
1447        outputs = [
1448          _actual_file,
1449          _failure_file,
1450        ]
1451        args = _args + [
1452                 "--depfile",
1453                 rebase_path(depfile, root_build_dir),
1454                 "--failure-file",
1455                 rebase_path(_failure_file, root_build_dir),
1456                 "--expected-file",
1457                 rebase_path(invoker.expected_proguard_config, root_build_dir),
1458                 "--actual-file",
1459                 rebase_path(_actual_file, root_build_dir),
1460                 "--only-verify-expectations",
1461               ]
1462        if (defined(invoker.expected_proguard_config_base)) {
1463          inputs += [ invoker.expected_proguard_config_base ]
1464          args += [
1465            "--expected-file-base",
1466            rebase_path(invoker.expected_proguard_config_base, root_build_dir),
1467          ]
1468        }
1469        if (fail_on_android_expectations) {
1470          args += [ "--fail-on-expectations" ]
1471        }
1472      }
1473      _deps += [ ":$_expectations_target" ]
1474    }
1475
1476    if (_enable_checks) {
1477      _tracerefs_json = "$target_gen_dir/$target_name.tracerefs.json"
1478      _proguard_target_name = "${target_name}__r8"
1479    } else {
1480      _proguard_target_name = target_name
1481    }
1482    action_with_pydeps(_proguard_target_name) {
1483      forward_variables_from(invoker,
1484                             [
1485                               "data",
1486                               "data_deps",
1487                               "public_deps",
1488                             ])
1489      script = _script
1490      deps = _deps
1491      inputs = _inputs
1492      outputs = _outputs
1493      depfile = "${target_gen_dir}/${target_name}.d"
1494      args = _args + _output_arg + [
1495               "--depfile",
1496               rebase_path(depfile, root_build_dir),
1497             ]
1498      if (_enable_checks) {
1499        outputs += [ _tracerefs_json ]
1500        args += [
1501          "--tracerefs-json",
1502          rebase_path(_tracerefs_json, root_build_dir),
1503        ]
1504      }
1505
1506      # http://crbug.com/725224. Fix for bots running out of memory.
1507      if (defined(java_cmd_pool_size)) {
1508        pool = "//build/config/android:java_cmd_pool($default_toolchain)"
1509      } else {
1510        pool = "//build/toolchain:link_pool($default_toolchain)"
1511      }
1512    }
1513
1514    if (_enable_checks) {
1515      trace_references(target_name) {
1516        tracerefs_json = _tracerefs_json
1517        public_deps = [ ":$_proguard_target_name" ]
1518      }
1519    }
1520  }
1521
1522  # Generates a script in the build bin directory to run a java binary.
1523  #
1524  # Variables
1525  #   main_class: The class containing the program entry point.
1526  #   build_config: Path to .build_config.json for the jar (contains classpath).
1527  #   script_name: Name of the script to generate.
1528  #   wrapper_script_args: List of extra arguments to pass to the executable.
1529  #   tiered_stop_at_level_one: Whether to pass --tiered-stop-at-level-one
1530  #
1531  template("java_binary_script") {
1532    action_with_pydeps(target_name) {
1533      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1534
1535      _main_class = invoker.main_class
1536      _build_config = invoker.build_config
1537      _script_name = invoker.script_name
1538      if (defined(invoker.max_heap_size)) {
1539        _max_heap_size = invoker.max_heap_size
1540      } else {
1541        _max_heap_size = "1G"
1542      }
1543
1544      script = "//build/android/gyp/create_java_binary_script.py"
1545      inputs = [ _build_config ]
1546      _java_script = "$root_build_dir/bin/$_script_name"
1547      outputs = [ _java_script ]
1548      _rebased_build_config = rebase_path(_build_config, root_build_dir)
1549      args = [
1550        "--output",
1551        rebase_path(_java_script, root_build_dir),
1552        "--main-class",
1553        _main_class,
1554        "--classpath=@FileArg($_rebased_build_config:deps_info:host_classpath)",
1555        "--max-heap-size=$_max_heap_size",
1556      ]
1557      data = []
1558      deps = [ "//third_party/jdk:java_data" ]
1559      if (defined(invoker.deps)) {
1560        deps += invoker.deps
1561      }
1562
1563      if (enable_java_asserts) {
1564        args += [ "--enable-asserts" ]
1565      }
1566      if (use_jacoco_coverage) {
1567        args += [
1568          "--classpath",
1569          rebase_path(_jacoco_host_jar, root_build_dir),
1570        ]
1571        data += [ _jacoco_host_jar ]
1572      }
1573      if (defined(invoker.tiered_stop_at_level_one) &&
1574          invoker.tiered_stop_at_level_one) {
1575        args += [ "--tiered-stop-at-level-one" ]
1576      }
1577      if (defined(invoker.extra_classpath_jars)) {
1578        _rebased_extra_classpath_jars =
1579            rebase_path(invoker.extra_classpath_jars, root_build_dir)
1580        args += [ "--classpath=${_rebased_extra_classpath_jars}" ]
1581        data += invoker.extra_classpath_jars
1582      }
1583      if (defined(invoker.wrapper_script_args)) {
1584        args += [ "--" ] + invoker.wrapper_script_args
1585      }
1586    }
1587  }
1588
1589  # Variables
1590  #   apply_mapping: The path to the ProGuard mapping file to apply.
1591  #   disable_incremental: Disable incremental dexing.
1592  template("dex") {
1593    _min_sdk_version = default_min_sdk_version
1594    if (defined(invoker.min_sdk_version)) {
1595      _min_sdk_version = invoker.min_sdk_version
1596    }
1597    assert(
1598        _min_sdk_version >= min_supported_sdk_version,
1599        get_label_info(":$target_name", "label_no_toolchain") + " has an unsupported min_sdk_version of $_min_sdk_version (min is $min_supported_sdk_version)")
1600
1601    _proguard_enabled =
1602        defined(invoker.proguard_enabled) && invoker.proguard_enabled
1603    _is_dex_merging = defined(invoker.input_dex_filearg)
1604    _enable_desugar = !defined(invoker.enable_desugar) || invoker.enable_desugar
1605
1606    # It's not safe to dex merge with libraries dex'ed at higher api versions.
1607    assert(!_is_dex_merging || _min_sdk_version >= default_min_sdk_version)
1608
1609    # For D8's backported method desugaring to work properly, the dex merge step
1610    # must not be set to a higher minSdkVersion than it was for the libraries.
1611    if (_enable_desugar && _is_dex_merging) {
1612      _min_sdk_version = default_min_sdk_version
1613    }
1614
1615    assert(defined(invoker.output) ||
1616           (_proguard_enabled && defined(invoker.modules)))
1617    assert(!_proguard_enabled || !(defined(invoker.input_dex_filearg) ||
1618                                       defined(invoker.input_classes_filearg) ||
1619                                       defined(invoker.input_class_jars)),
1620           "Cannot explicitly set inputs when proguarding a dex.")
1621
1622    # Dex merging should not also be dexing.
1623    assert(!(_is_dex_merging && defined(invoker.input_classes_filearg)))
1624    assert(!(_is_dex_merging && defined(invoker.input_class_jars)))
1625
1626    assert(!(defined(invoker.apply_mapping) && !_proguard_enabled),
1627           "apply_mapping can only be specified if proguard is enabled.")
1628    if (defined(invoker.custom_assertion_handler)) {
1629      assert(_proguard_enabled,
1630             "Proguard is required to support the custom assertion handler.")
1631    }
1632
1633    if (_proguard_enabled) {
1634      _proguard_target_name = target_name
1635
1636      proguard(_proguard_target_name) {
1637        forward_variables_from(invoker,
1638                               TESTONLY_AND_VISIBILITY + [
1639                                     "add_view_trace_events",
1640                                     "apply_mapping",
1641                                     "build_config",
1642                                     "custom_assertion_handler",
1643                                     "data",
1644                                     "data_deps",
1645                                     "deps",
1646                                     "enable_proguard_checks",
1647                                     "expected_proguard_config",
1648                                     "expected_proguard_config_base",
1649                                     "has_apk_under_test",
1650                                     "ignore_desugar_missing_deps",
1651                                     "inputs",
1652                                     "modules",
1653                                     "output",
1654                                     "package_name",
1655                                     "proguard_args",
1656                                     "proguard_configs",
1657                                     "proguard_enable_obfuscation",
1658                                     "proguard_mapping_path",
1659                                     "proguard_sourcefile_suffix",
1660                                     "repackage_classes",
1661                                     "top_target_name",
1662                                     "version_code",
1663                                   ])
1664        min_sdk_version = _min_sdk_version
1665      }
1666    } else {  # !_proguard_enabled
1667      _is_library = defined(invoker.is_library) && invoker.is_library
1668      assert(!(defined(invoker.input_classes_filearg) && _is_library))
1669      assert(_is_library == defined(invoker.unprocessed_jar_path))
1670      _input_class_jars = []
1671      if (defined(invoker.input_class_jars)) {
1672        _input_class_jars = invoker.input_class_jars
1673      }
1674      _deps = invoker.deps
1675
1676      if (_input_class_jars != []) {
1677        _rebased_input_class_jars =
1678            rebase_path(_input_class_jars, root_build_dir)
1679      }
1680
1681      action_with_pydeps(target_name) {
1682        forward_variables_from(invoker,
1683                               TESTONLY_AND_VISIBILITY + [
1684                                     "data",
1685                                     "data_deps",
1686                                   ])
1687        script = "//build/android/gyp/dex.py"
1688        deps = _deps
1689        depfile = "$target_gen_dir/$target_name.d"
1690        outputs = [ invoker.output ]
1691        inputs = [
1692                   "$android_sdk/optional/android.test.base.jar",
1693                   "$android_sdk/optional/org.apache.http.legacy.jar",
1694                   "//third_party/jdk/current/bin/java",
1695                   _custom_d8_path,
1696                   _d8_path,
1697                   android_sdk_jar,
1698                   invoker.build_config,
1699                 ] + java_paths_for_inputs
1700        if (defined(invoker.inputs)) {
1701          inputs += invoker.inputs
1702        }
1703
1704        if (!_is_library) {
1705          # http://crbug.com/725224. Fix for bots running out of memory.
1706          if (defined(java_cmd_pool_size)) {
1707            pool = "//build/config/android:java_cmd_pool($default_toolchain)"
1708          } else {
1709            pool = "//build/toolchain:link_pool($default_toolchain)"
1710          }
1711        }
1712
1713        args = [
1714          "--depfile",
1715          rebase_path(depfile, root_build_dir),
1716          "--output",
1717          rebase_path(invoker.output, root_build_dir),
1718          "--min-api=$_min_sdk_version",
1719          "--r8-jar-path",
1720          rebase_path(_d8_path, root_build_dir),
1721          "--custom-d8-jar-path",
1722          rebase_path(_custom_d8_path, root_build_dir),
1723
1724          # Uncomment when rebuilding custom_d8.jar.
1725          #"--skip-custom-d8",
1726        ]
1727        if (treat_warnings_as_errors) {
1728          args += [ "--warnings-as-errors" ]
1729        }
1730
1731        if (enable_incremental_d8 && !(defined(invoker.disable_incremental) &&
1732                                       invoker.disable_incremental)) {
1733          # Don't use incremental dexing for ProGuarded inputs as a precaution.
1734          args += [
1735            "--incremental-dir",
1736            rebase_path("$target_out_dir/$target_name", root_build_dir),
1737          ]
1738        }
1739        if (_is_library) {
1740          args += [ "--library" ]
1741        }
1742        if (defined(invoker.input_dex_filearg)) {
1743          args += [ "--dex-inputs-filearg=${invoker.input_dex_filearg}" ]
1744        }
1745        if (defined(invoker.input_classes_filearg)) {
1746          args += [ "--class-inputs-filearg=${invoker.input_classes_filearg}" ]
1747
1748          # Required for the same reason as unprocessed_jar_path is added to
1749          # classpath (see note below).
1750          args += [ "--classpath=${invoker.input_classes_filearg}" ]
1751        }
1752        if (_input_class_jars != []) {
1753          inputs += _input_class_jars
1754          args += [ "--class-inputs=${_rebased_input_class_jars}" ]
1755        }
1756
1757        # Never compile intemediates with --release in order to:
1758        # 1) not require recompiles when toggling is_java_debug,
1759        # 2) allow incremental_install=1 to still have local variable
1760        #    information even when is_java_debug=false.
1761        if (!is_java_debug && !_is_library) {
1762          args += [ "--release" ]
1763        }
1764
1765        if (_enable_desugar) {
1766          args += [ "--desugar" ]
1767
1768          _ignore_desugar_missing_deps =
1769              defined(invoker.ignore_desugar_missing_deps) &&
1770              invoker.ignore_desugar_missing_deps
1771          if (!_ignore_desugar_missing_deps) {
1772            args += [ "--show-desugar-default-interface-warnings" ]
1773          }
1774
1775          # Cannot use header jar for the active jar, because it does not
1776          # contain anonymous classes. https://crbug.com/1342018#c5
1777          # Cannot use processed .jar here because it might have classes
1778          # filtered out via jar_excluded_patterns.
1779          # Must come first in classpath in order to take precedence over
1780          # deps that defined the same classes (via jar_excluded_patterns).
1781          _rebased_build_config =
1782              rebase_path(invoker.build_config, root_build_dir)
1783          if (defined(invoker.unprocessed_jar_path)) {
1784            args += [
1785              "--classpath",
1786              rebase_path(invoker.unprocessed_jar_path, root_build_dir),
1787
1788              # Pass the full classpath to find new dependencies that are not in
1789              # the .desugardeps file.
1790              "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)",
1791            ]
1792            inputs += [ invoker.unprocessed_jar_path ]
1793          }
1794          _desugar_dependencies_path =
1795              "$target_gen_dir/$target_name.desugardeps"
1796          args += [
1797            "--desugar-dependencies",
1798            rebase_path(_desugar_dependencies_path, root_build_dir),
1799            "--bootclasspath=@FileArg($_rebased_build_config:android:sdk_jars)",
1800          ]
1801        }
1802
1803        if (defined(invoker.custom_assertion_handler)) {
1804          args += [
1805            "--assertion-handler",
1806            invoker.custom_assertion_handler,
1807          ]
1808        } else if (enable_java_asserts) {
1809          # The default for generating dex file format is
1810          # --force-disable-assertions.
1811          args += [ "--force-enable-assertions" ]
1812        }
1813      }
1814    }
1815  }
1816
1817  template("jacoco_instr") {
1818    action_with_pydeps(target_name) {
1819      forward_variables_from(invoker,
1820                             TESTONLY_AND_VISIBILITY + [
1821                                   "deps",
1822                                   "public_deps",
1823                                 ])
1824
1825      # The name needs to match the SOURCES_JSON_FILES_SUFFIX in
1826      # generate_coverage_metadata_for_java.py.
1827      _sources_json_file = "$target_out_dir/${target_name}__jacoco_sources.json"
1828      _jacococli_jar = "//third_party/jacoco/cipd/lib/jacococli.jar"
1829
1830      script = "//build/android/gyp/jacoco_instr.py"
1831      inputs = invoker.source_files + java_paths_for_inputs + [
1832                 _jacococli_jar,
1833                 invoker.input_jar_path,
1834               ]
1835      outputs = [
1836        _sources_json_file,
1837        invoker.output_jar_path,
1838      ]
1839      args = [
1840        "--root-build-dir",
1841        root_build_dir,
1842        "--input-path",
1843        rebase_path(invoker.input_jar_path, root_build_dir),
1844        "--output-path",
1845        rebase_path(invoker.output_jar_path, root_build_dir),
1846        "--sources-json-file",
1847        rebase_path(_sources_json_file, root_build_dir),
1848        "--target-sources-file",
1849        rebase_path(invoker.target_sources_file, root_build_dir),
1850        "--jacococli-jar",
1851        rebase_path(_jacococli_jar, root_build_dir),
1852      ]
1853      if (coverage_instrumentation_input_file != "") {
1854        args += [
1855          "--files-to-instrument",
1856          rebase_path(coverage_instrumentation_input_file, root_build_dir),
1857        ]
1858      }
1859    }
1860  }
1861
1862  template("filter_jar") {
1863    action_with_pydeps(target_name) {
1864      script = "//build/android/gyp/filter_zip.py"
1865      forward_variables_from(invoker,
1866                             TESTONLY_AND_VISIBILITY + [
1867                                   "deps",
1868                                   "data",
1869                                   "data_deps",
1870                                 ])
1871      inputs = [ invoker.input_jar ]
1872      if (defined(invoker.inputs)) {
1873        inputs += invoker.inputs
1874      }
1875      outputs = [ invoker.output_jar ]
1876
1877      _jar_excluded_patterns = []
1878      if (defined(invoker.jar_excluded_patterns)) {
1879        _jar_excluded_patterns = invoker.jar_excluded_patterns
1880      }
1881      _jar_included_patterns = []
1882      if (defined(invoker.jar_included_patterns)) {
1883        _jar_included_patterns = invoker.jar_included_patterns
1884      }
1885      args = [
1886        "--input",
1887        rebase_path(invoker.input_jar, root_build_dir),
1888        "--output",
1889        rebase_path(invoker.output_jar, root_build_dir),
1890        "--exclude-globs=${_jar_excluded_patterns}",
1891        "--include-globs=${_jar_included_patterns}",
1892      ]
1893    }
1894  }
1895
1896  template("process_java_library") {
1897    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
1898
1899    _previous_output_jar = invoker.input_jar_path
1900
1901    if (invoker.jacoco_instrument) {
1902      _filter_jar_target_name = "${target_name}__filter_jar"
1903      _filter_jar_output_jar = "$target_out_dir/$target_name.filter.jar"
1904    } else {
1905      _filter_jar_target_name = target_name
1906      _filter_jar_output_jar = invoker.output_jar_path
1907    }
1908
1909    filter_jar(_filter_jar_target_name) {
1910      forward_variables_from(invoker,
1911                             [
1912                               "data",
1913                               "data_deps",
1914                               "jar_excluded_patterns",
1915                               "jar_included_patterns",
1916                             ])
1917      deps = invoker.deps
1918      input_jar = _previous_output_jar
1919      output_jar = _filter_jar_output_jar
1920    }
1921
1922    if (invoker.jacoco_instrument) {
1923      # Jacoco must run after desugar (or else desugar sometimes fails).
1924      # It must run after filtering to avoid the same (filtered) class mapping
1925      # to multiple .jar files.
1926      # We run offline code coverage processing here rather than with a
1927      # javaagent as the desired coverage data was not being generated.
1928      # See crbug.com/1097815.
1929      jacoco_instr(target_name) {
1930        deps = [ ":$_filter_jar_target_name" ] + invoker.deps
1931        forward_variables_from(invoker,
1932                               [
1933                                 "source_files",
1934                                 "target_sources_file",
1935                               ])
1936
1937        input_jar_path = _filter_jar_output_jar
1938        output_jar_path = invoker.output_jar_path
1939      }
1940    }
1941  }
1942
1943  template("check_for_missing_direct_deps") {
1944    action_with_pydeps(target_name) {
1945      forward_variables_from(invoker,
1946                             TESTONLY_AND_VISIBILITY + [
1947                                   "data_deps",
1948                                   "deps",
1949                                 ])
1950      script = "//build/android/gyp/check_for_missing_direct_deps.py"
1951      inputs = java_paths_for_inputs + [
1952                 invoker.build_config,
1953                 invoker.input_jar,
1954               ]
1955      depfile = "$target_gen_dir/$target_name.d"
1956      outputs = [ "$target_out_dir/$target_name.bytecode.stamp" ]
1957      _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
1958      args = [
1959        "--depfile",
1960        rebase_path(depfile, root_build_dir),
1961        "--target-name",
1962        get_label_info(":${target_name}", "label_no_toolchain"),
1963        "--gn-target=${invoker.target_label}",
1964        "--input-jar",
1965        rebase_path(invoker.input_jar, root_build_dir),
1966        "--stamp",
1967        rebase_path(outputs[0], root_build_dir),
1968        "--chromium-output-dir",
1969        rebase_path(root_build_dir, root_build_dir),
1970        "--direct-classpath-jars=@FileArg($_rebased_build_config:javac:classpath)",
1971        "--full-classpath-jars=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)",
1972        "--full-classpath-gn-targets=@FileArg($_rebased_build_config:deps_info:javac_full_classpath_targets)",
1973      ]
1974      if (auto_add_missing_java_deps) {
1975        args += [ "--auto-add-deps" ]
1976      }
1977      if (android_static_analysis == "build_server") {
1978        args += [ "--use-build-server" ]
1979      }
1980      if (invoker.include_android_sdk) {
1981        args += [ "--sdk-classpath-jars=@FileArg($_rebased_build_config:android:sdk_jars)" ]
1982      }
1983      if (treat_warnings_as_errors) {
1984        args += [ "--warnings-as-errors" ]
1985      }
1986    }
1987  }
1988
1989  template("merge_manifests") {
1990    action_with_pydeps(target_name) {
1991      assert(
1992          invoker.min_sdk_version >= min_supported_sdk_version,
1993          get_label_info(":$target_name", "label_no_toolchain") + " has an unsupported min_sdk_version of ${invoker.min_sdk_version} (min is $min_supported_sdk_version)")
1994      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
1995      script = "//build/android/gyp/merge_manifest.py"
1996      depfile = "$target_gen_dir/$target_name.d"
1997
1998      inputs = java_paths_for_inputs + [
1999                 invoker.build_config,
2000                 invoker.input_manifest,
2001                 _manifest_merger_jar_path,
2002               ]
2003
2004      outputs = [ invoker.output_manifest ]
2005      _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
2006
2007      args = [
2008        "--depfile",
2009        rebase_path(depfile, root_build_dir),
2010        "--manifest-merger-jar",
2011        rebase_path(_manifest_merger_jar_path, root_build_dir),
2012        "--root-manifest",
2013        rebase_path(invoker.input_manifest, root_build_dir),
2014        "--output",
2015        rebase_path(invoker.output_manifest, root_build_dir),
2016        "--extras",
2017        "@FileArg($_rebased_build_config:deps_info:extra_android_manifests)",
2018        "--min-sdk-version=${invoker.min_sdk_version}",
2019        "--target-sdk-version=${invoker.target_sdk_version}",
2020      ]
2021
2022      if (defined(invoker.manifest_package)) {
2023        args += [ "--manifest-package=${invoker.manifest_package}" ]
2024      }
2025
2026      if (defined(invoker.max_sdk_version)) {
2027        args += [ "--max-sdk-version=${invoker.max_sdk_version}" ]
2028      }
2029
2030      if (treat_warnings_as_errors) {
2031        args += [ "--warnings-as-errors" ]
2032      }
2033    }
2034  }
2035
2036  # This template is used to parse a set of resource directories and
2037  # create the R.txt, .srcjar and .resources.zip for it.
2038  #
2039  # Input variables:
2040  #   deps: Specifies the input dependencies for this target.
2041  #
2042  #   build_config: Path to the .build_config.json file corresponding to the target.
2043  #
2044  #   sources:
2045  #     List of input resource files.
2046  #
2047  #   custom_package: (optional)
2048  #     Package name for the generated R.java source file. Optional if
2049  #     android_manifest is not provided.
2050  #
2051  #   android_manifest: (optional)
2052  #     If custom_package is not provided, path to an AndroidManifest.xml file
2053  #     that is only used to extract a package name out of it.
2054  #
2055  #   r_text_in_path: (optional)
2056  #     Path to an input R.txt file to use to generate the R.java file.
2057  #     The default is to use 'aapt' to generate the file from the content
2058  #     of the resource directories.
2059  #
2060  # Output variables:
2061  #   resources_zip:
2062  #     Path to a .resources.zip that will simply contain all the
2063  #     input resources, collected in a single archive.
2064  #
2065  #   r_text_out_path: Path for the generated R.txt file.
2066  #
2067  template("prepare_resources") {
2068    action_with_pydeps(target_name) {
2069      forward_variables_from(invoker,
2070                             TESTONLY_AND_VISIBILITY + [
2071                                   "deps",
2072                                   "public_deps",
2073                                   "sources",
2074                                 ])
2075      script = "//build/android/gyp/prepare_resources.py"
2076
2077      depfile = "$target_gen_dir/${invoker.target_name}.d"
2078      outputs = [
2079        invoker.resources_zip,
2080        invoker.resources_zip + ".info",
2081        invoker.r_text_out_path,
2082      ]
2083
2084      inputs = [ invoker.res_sources_path ]
2085
2086      _rebased_res_sources_path =
2087          rebase_path(invoker.res_sources_path, root_build_dir)
2088
2089      args = [
2090        "--depfile",
2091        rebase_path(depfile, root_build_dir),
2092        "--res-sources-path=$_rebased_res_sources_path",
2093        "--resource-zip-out",
2094        rebase_path(invoker.resources_zip, root_build_dir),
2095        "--r-text-out",
2096        rebase_path(invoker.r_text_out_path, root_build_dir),
2097      ]
2098
2099      if (defined(invoker.r_text_in_path)) {
2100        _r_text_in_path = invoker.r_text_in_path
2101        inputs += [ _r_text_in_path ]
2102        args += [
2103          "--r-text-in",
2104          rebase_path(_r_text_in_path, root_build_dir),
2105        ]
2106      }
2107
2108      if (defined(invoker.strip_drawables) && invoker.strip_drawables) {
2109        args += [ "--strip-drawables" ]
2110      }
2111      if (defined(invoker.allow_missing_resources) &&
2112          invoker.allow_missing_resources) {
2113        args += [ "--allow-missing-resources" ]
2114      }
2115    }
2116  }
2117
2118  # A template that is used to compile all resources needed by a binary
2119  # (e.g. an android_apk or a robolectric_binary) into an intermediate .ar_
2120  # archive. It can also generate an associated .srcjar that contains the
2121  # final R.java sources for all resource packages the binary depends on.
2122  #
2123  # Input variables:
2124  #   android_sdk_dep: The sdk dep that these resources should compile against.
2125  #
2126  #   deps: Specifies the input dependencies for this target.
2127  #
2128  #   build_config: Path to the .build_config.json file corresponding to the target.
2129  #
2130  #   build_config_dep: Dep target to generate the .build_config.json file.
2131  #
2132  #   android_manifest: Path to root manifest for the binary.
2133  #
2134  #   version_code: (optional)
2135  #
2136  #   version_name: (optional)
2137  #
2138  #   shared_resources: (optional)
2139  #     If true, make all variables in each generated R.java file non-final,
2140  #     and provide an onResourcesLoaded() method that can be used to reset
2141  #     their package index at load time. Useful when the APK corresponds to
2142  #     a library that is loaded at runtime, like system_webview_apk or
2143  #     monochrome_apk.
2144  #
2145  #   app_as_shared_lib: (optional)
2146  #     If true, same effect as shared_resources, but also ensures that the
2147  #     resources can be used by the APK when it is loaded as a regular
2148  #     application as well. Useful for the monochrome_public_apk target
2149  #     which is both an application and a shared runtime library that
2150  #     implements the system webview feature.
2151  #
2152  #   shared_resources_allowlist: (optional)
2153  #     Path to an R.txt file. If provided, acts similar to shared_resources
2154  #     except that it restricts the list of non-final resource variables
2155  #     to the list from the input R.txt file. Overrides shared_resources
2156  #     when both are specified.
2157  #
2158  #   shared_resources_allowlist_locales: (optional)
2159  #     If shared_resources_allowlist is used, provide an optional list of
2160  #     Chromium locale names to determine which localized shared string
2161  #     resources to put in the final output, even if aapt_locale_allowlist
2162  #     is defined to a smaller subset.
2163  #
2164  #   aapt_locale_allowlist: (optional)
2165  #     Restrict compiled locale-dependent resources to a specific allowlist.
2166  #     NOTE: This is a list of Chromium locale names, not Android ones.
2167  #
2168  #   r_java_root_package_name: (optional)
2169  #     Short package name for this target's root R java file (ex. input of
2170  #     "base" would become "gen.base_module" for the root R java package name).
2171  #     Optional as defaults to "base".
2172  #
2173  #   resource_exclusion_regex: (optional)
2174  #
2175  #   resource_exclusion_exceptions: (optional)
2176  #
2177  #   resource_values_filter_rules: (optional)
2178  #
2179  #   png_to_webp: (optional)
2180  #     If true, convert all PNG resources (except 9-patch files) to WebP.
2181  #
2182  #   post_process_script: (optional)
2183  #
2184  #   package_name: (optional)
2185  #     Name of the package for the purpose of creating R class.
2186  #
2187  #   package_id: (optional)
2188  #     Use a custom package ID in resource IDs.
2189  #
2190  #   arsc_package_name: (optional)
2191  #     Use this package name in the arsc file rather than the package name
2192  #     found in the AndroidManifest.xml. Does not affect the package name
2193  #     used in AndroidManifest.xml.
2194  #
2195  #   resource_ids_provider_dep: (optional)
2196  #     Use resource IDs provided by another APK target when compiling resources
2197  #     (via. "aapt2 link --stable-ids")
2198  #
2199  #   override_target_sdk: (optional)
2200  #     Update the manifest to target this SDK
2201  #
2202  # Output variables:
2203  #   arsc_output: Path to output .ap_ file (optional).
2204  #
2205  #   proto_output: Path to output .proto.ap_ file (optional).
2206  #
2207  #   r_text_out_path: (optional):
2208  #       Path for the corresponding generated R.txt file.
2209  #
2210  #   proguard_file: (optional)
2211  #       Path to proguard configuration file for this apk target.
2212  #
2213  template("compile_resources") {
2214    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
2215
2216    _deps = invoker.deps + [ invoker.build_config_dep ]
2217    if (defined(invoker.android_manifest_dep)) {
2218      _deps += [ invoker.android_manifest_dep ]
2219    }
2220
2221    if (defined(invoker.arsc_output)) {
2222      _arsc_output = invoker.arsc_output
2223    }
2224    _final_srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
2225
2226    _script = "//build/android/gyp/compile_resources.py"
2227
2228    _target_sdk_version = invoker.target_sdk_version
2229    if (defined(invoker.override_target_sdk)) {
2230      _target_sdk_version = invoker.override_target_sdk
2231    }
2232
2233    _common_inputs = [
2234      invoker.build_config,
2235      android_sdk_tools_bundle_aapt2,
2236      android_sdk_jar,
2237
2238      # TODO(b/315080809#comment4): remove these files after fixing
2239      # build/print_python_deps.py.
2240      "//third_party/protobuf/python/google/__init__.py",
2241      "//third_party/protobuf/python/google/protobuf/__init__.py",
2242      "//third_party/protobuf/python/google/protobuf/compiler/__init__.py",
2243      "//third_party/protobuf/python/google/protobuf/compiler/plugin_pb2.py",
2244      "//third_party/protobuf/python/google/protobuf/descriptor.py",
2245      "//third_party/protobuf/python/google/protobuf/descriptor_database.py",
2246      "//third_party/protobuf/python/google/protobuf/descriptor_pb2.py",
2247      "//third_party/protobuf/python/google/protobuf/descriptor_pool.py",
2248      "//third_party/protobuf/python/google/protobuf/internal/__init__.py",
2249      "//third_party/protobuf/python/google/protobuf/internal/_parameterized.py",
2250      "//third_party/protobuf/python/google/protobuf/internal/api_implementation.py",
2251      "//third_party/protobuf/python/google/protobuf/internal/builder.py",
2252      "//third_party/protobuf/python/google/protobuf/internal/containers.py",
2253      "//third_party/protobuf/python/google/protobuf/internal/decoder.py",
2254      "//third_party/protobuf/python/google/protobuf/internal/descriptor_database_test.py",
2255      "//third_party/protobuf/python/google/protobuf/internal/descriptor_pool_test.py",
2256      "//third_party/protobuf/python/google/protobuf/internal/descriptor_test.py",
2257      "//third_party/protobuf/python/google/protobuf/internal/encoder.py",
2258      "//third_party/protobuf/python/google/protobuf/internal/enum_type_wrapper.py",
2259      "//third_party/protobuf/python/google/protobuf/internal/extension_dict.py",
2260      "//third_party/protobuf/python/google/protobuf/internal/field_mask.py",
2261      "//third_party/protobuf/python/google/protobuf/internal/generator_test.py",
2262      "//third_party/protobuf/python/google/protobuf/internal/import_test.py",
2263      "//third_party/protobuf/python/google/protobuf/internal/import_test_package/__init__.py",
2264      "//third_party/protobuf/python/google/protobuf/internal/json_format_test.py",
2265      "//third_party/protobuf/python/google/protobuf/internal/keywords_test.py",
2266      "//third_party/protobuf/python/google/protobuf/internal/message_factory_test.py",
2267      "//third_party/protobuf/python/google/protobuf/internal/message_listener.py",
2268      "//third_party/protobuf/python/google/protobuf/internal/message_test.py",
2269      "//third_party/protobuf/python/google/protobuf/internal/proto_builder_test.py",
2270      "//third_party/protobuf/python/google/protobuf/internal/python_edition_defaults.py",
2271      "//third_party/protobuf/python/google/protobuf/internal/python_message.py",
2272      "//third_party/protobuf/python/google/protobuf/internal/reflection_test.py",
2273      "//third_party/protobuf/python/google/protobuf/internal/service_reflection_test.py",
2274      "//third_party/protobuf/python/google/protobuf/internal/symbol_database_test.py",
2275      "//third_party/protobuf/python/google/protobuf/internal/test_util.py",
2276      "//third_party/protobuf/python/google/protobuf/internal/testing_refleaks.py",
2277      "//third_party/protobuf/python/google/protobuf/internal/text_encoding_test.py",
2278      "//third_party/protobuf/python/google/protobuf/internal/text_format_test.py",
2279      "//third_party/protobuf/python/google/protobuf/internal/type_checkers.py",
2280      "//third_party/protobuf/python/google/protobuf/internal/unknown_fields_test.py",
2281      "//third_party/protobuf/python/google/protobuf/internal/well_known_types.py",
2282      "//third_party/protobuf/python/google/protobuf/internal/well_known_types_test.py",
2283      "//third_party/protobuf/python/google/protobuf/internal/wire_format.py",
2284      "//third_party/protobuf/python/google/protobuf/internal/wire_format_test.py",
2285      "//third_party/protobuf/python/google/protobuf/json_format.py",
2286      "//third_party/protobuf/python/google/protobuf/message.py",
2287      "//third_party/protobuf/python/google/protobuf/message_factory.py",
2288      "//third_party/protobuf/python/google/protobuf/proto_builder.py",
2289      "//third_party/protobuf/python/google/protobuf/pyext/__init__.py",
2290      "//third_party/protobuf/python/google/protobuf/pyext/cpp_message.py",
2291      "//third_party/protobuf/python/google/protobuf/reflection.py",
2292      "//third_party/protobuf/python/google/protobuf/runtime_version.py",
2293      "//third_party/protobuf/python/google/protobuf/service.py",
2294      "//third_party/protobuf/python/google/protobuf/service_reflection.py",
2295      "//third_party/protobuf/python/google/protobuf/symbol_database.py",
2296      "//third_party/protobuf/python/google/protobuf/text_encoding.py",
2297      "//third_party/protobuf/python/google/protobuf/text_format.py",
2298      "//third_party/protobuf/python/google/protobuf/unknown_fields.py",
2299      "//third_party/protobuf/python/google/protobuf/util/__init__.py",
2300    ]
2301
2302    _inputs = _common_inputs
2303
2304    _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
2305
2306    _rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir)
2307    _args = [
2308      "--include-resources=$_rebased_android_sdk_jar",
2309      "--aapt2-path",
2310      rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
2311      "--dependencies-res-zips=@FileArg($_rebased_build_config:deps_info:dependency_zips)",
2312      "--extra-res-packages=@FileArg($_rebased_build_config:deps_info:extra_package_names)",
2313      "--min-sdk-version=${invoker.min_sdk_version}",
2314      "--target-sdk-version=${_target_sdk_version}",
2315      "--webp-cache-dir=obj/android-webp-cache",
2316    ]
2317
2318    _inputs += [ invoker.android_manifest ]
2319    _outputs = [ _final_srcjar_path ]
2320    _args += [
2321      "--android-manifest",
2322      rebase_path(invoker.android_manifest, root_build_dir),
2323      "--srcjar-out",
2324      rebase_path(_final_srcjar_path, root_build_dir),
2325    ]
2326    if (defined(invoker.version_code)) {
2327      _args += [
2328        "--version-code",
2329        invoker.version_code,
2330      ]
2331    }
2332    if (defined(invoker.version_name)) {
2333      _args += [
2334        "--version-name",
2335        invoker.version_name,
2336      ]
2337    }
2338    if (defined(_arsc_output)) {
2339      _outputs += [ _arsc_output ]
2340      _args += [
2341        "--arsc-path",
2342        rebase_path(_arsc_output, root_build_dir),
2343      ]
2344    }
2345    if (defined(invoker.proto_output)) {
2346      _outputs += [ invoker.proto_output ]
2347      _args += [
2348        "--proto-path",
2349        rebase_path(invoker.proto_output, root_build_dir),
2350      ]
2351    }
2352    if (defined(invoker.size_info_path)) {
2353      _outputs += [ invoker.size_info_path ]
2354      _args += [
2355        "--info-path",
2356        rebase_path(invoker.size_info_path, root_build_dir),
2357      ]
2358    }
2359
2360    if (defined(invoker.r_java_root_package_name)) {
2361      _args += [
2362        "--r-java-root-package-name",
2363        invoker.r_java_root_package_name,
2364      ]
2365    }
2366
2367    # Useful to have android:debuggable in the manifest even for Release
2368    # builds. Just omit it for officai
2369    if (debuggable_apks) {
2370      _args += [ "--debuggable" ]
2371    }
2372
2373    if (defined(invoker.r_text_out_path)) {
2374      _outputs += [ invoker.r_text_out_path ]
2375      _args += [
2376        "--r-text-out",
2377        rebase_path(invoker.r_text_out_path, root_build_dir),
2378      ]
2379    }
2380
2381    if (defined(invoker.rename_manifest_package)) {
2382      _args += [
2383        "--rename-manifest-package",
2384        invoker.rename_manifest_package,
2385      ]
2386    }
2387
2388    # Define the flags related to shared resources.
2389    #
2390    # Note the small sanity check to ensure that the package ID of the
2391    # generated resources table is correct. It should be 0x02 for runtime
2392    # shared libraries, and 0x7f otherwise.
2393
2394    if (defined(invoker.shared_resources) && invoker.shared_resources) {
2395      _args += [ "--shared-resources" ]
2396    }
2397    if (defined(invoker.app_as_shared_lib) && invoker.app_as_shared_lib) {
2398      _args += [ "--app-as-shared-lib" ]
2399    }
2400    if (defined(invoker.package_id)) {
2401      _args += [ "--package-id=${invoker.package_id}" ]
2402    }
2403    if (defined(invoker.package_name)) {
2404      _args += [
2405        "--package-name",
2406        invoker.package_name,
2407      ]
2408    }
2409    if (defined(invoker.arsc_package_name)) {
2410      _args += [
2411        "--arsc-package-name",
2412        invoker.arsc_package_name,
2413      ]
2414    }
2415
2416    if (defined(invoker.shared_resources_allowlist)) {
2417      _inputs += [ invoker.shared_resources_allowlist ]
2418      _args += [
2419        "--shared-resources-allowlist",
2420        rebase_path(invoker.shared_resources_allowlist, root_build_dir),
2421      ]
2422    }
2423    if (defined(invoker.shared_resources_allowlist_locales)) {
2424      _args += [ "--shared-resources-allowlist-locales=" +
2425                 "${invoker.shared_resources_allowlist_locales}" ]
2426    }
2427
2428    if (!defined(testonly) || !testonly ||
2429        (defined(invoker.enforce_resource_overlays_in_tests) &&
2430         invoker.enforce_resource_overlays_in_tests)) {
2431      _args += [ "--dependencies-res-zip-overlays=@FileArg($_rebased_build_config:deps_info:dependency_zip_overlays)" ]
2432    } else {
2433      _args += [ "--dependencies-res-zip-overlays=@FileArg($_rebased_build_config:deps_info:dependency_zips)" ]
2434    }
2435
2436    if (defined(invoker.proguard_file)) {
2437      _outputs += [ invoker.proguard_file ]
2438      _args += [
2439        "--proguard-file",
2440        rebase_path(invoker.proguard_file, root_build_dir),
2441      ]
2442    }
2443
2444    if (defined(invoker.aapt_locale_allowlist)) {
2445      _args += [ "--locale-allowlist=${invoker.aapt_locale_allowlist}" ]
2446    }
2447    if (defined(invoker.png_to_webp) && invoker.png_to_webp) {
2448      _webp_target = "//third_party/libwebp:cwebp($host_toolchain)"
2449      _webp_binary = get_label_info(_webp_target, "root_out_dir") + "/cwebp"
2450      _deps += [ _webp_target ]
2451      _inputs += [ _webp_binary ]
2452      _args += [
2453        "--png-to-webp",
2454        "--webp-binary",
2455        rebase_path(_webp_binary, root_build_dir),
2456      ]
2457    }
2458    if (defined(invoker.resource_exclusion_regex)) {
2459      _args +=
2460          [ "--resource-exclusion-regex=${invoker.resource_exclusion_regex}" ]
2461      if (defined(invoker.resource_exclusion_exceptions)) {
2462        _args += [ "--resource-exclusion-exceptions=${invoker.resource_exclusion_exceptions}" ]
2463      }
2464    }
2465    if (defined(invoker.resource_values_filter_rules)) {
2466      _args +=
2467          [ "--values-filter-rules=${invoker.resource_values_filter_rules}" ]
2468    }
2469
2470    if (defined(invoker.include_resource)) {
2471      _inputs += [ invoker.include_resource ]
2472      _rebased_include_resources =
2473          rebase_path(invoker.include_resource, root_build_dir)
2474      _args += [ "--include-resources=$_rebased_include_resources" ]
2475    }
2476
2477    if (defined(invoker._args)) {
2478      _args += invoker._args
2479    }
2480
2481    if (defined(invoker.emit_ids_out_path)) {
2482      _outputs += [ invoker.emit_ids_out_path ]
2483      _rebased_emit_ids_path =
2484          rebase_path(invoker.emit_ids_out_path, root_out_dir)
2485      _args += [ "--emit-ids-out=$_rebased_emit_ids_path" ]
2486    }
2487
2488    if (defined(invoker.resource_ids_provider_dep)) {
2489      _compile_res_dep =
2490          "${invoker.resource_ids_provider_dep}__compile_resources"
2491      _gen_dir = get_label_info(_compile_res_dep, "target_gen_dir")
2492      _name = get_label_info(_compile_res_dep, "name")
2493      _resource_ids_path = "$_gen_dir/$_name.resource_ids"
2494      _inputs += [ _resource_ids_path ]
2495      _rebased_ids_path = rebase_path(_resource_ids_path, root_out_dir)
2496      _args += [ "--use-resource-ids-path=$_rebased_ids_path" ]
2497      _deps += [ _compile_res_dep ]
2498    }
2499
2500    if (defined(invoker.max_sdk_version)) {
2501      _max_sdk_version = invoker.max_sdk_version
2502      _args += [ "--max-sdk-version=$_max_sdk_version" ]
2503    }
2504
2505    if (defined(invoker.manifest_package)) {
2506      _args += [ "--manifest-package=${invoker.manifest_package}" ]
2507    }
2508
2509    if (defined(invoker.is_bundle_module) && invoker.is_bundle_module) {
2510      _args += [ "--is-bundle-module" ]
2511    }
2512
2513    if (defined(invoker.uses_split)) {
2514      assert(invoker.is_bundle_module)
2515      _args += [ "--uses-split=${invoker.uses_split}" ]
2516    }
2517
2518    if (defined(invoker.expected_android_manifest)) {
2519      _expectations_target =
2520          "${invoker.top_target_name}_validate_android_manifest"
2521      action_with_pydeps(_expectations_target) {
2522        _actual_file = "${invoker.android_manifest}.normalized"
2523        _failure_file =
2524            "$expectations_failure_dir/" +
2525            string_replace(invoker.expected_android_manifest, "/", "_")
2526        inputs = [
2527                   invoker.android_manifest,
2528                   invoker.expected_android_manifest,
2529                 ] + _common_inputs
2530        outputs = [
2531          _actual_file,
2532          _failure_file,
2533        ]
2534        deps = [
2535          invoker.android_manifest_dep,
2536          invoker.build_config_dep,
2537        ]
2538        script = _script
2539        args = _args + [
2540                 "--expected-file",
2541                 rebase_path(invoker.expected_android_manifest, root_build_dir),
2542                 "--actual-file",
2543                 rebase_path(_actual_file, root_build_dir),
2544                 "--failure-file",
2545                 rebase_path(_failure_file, root_build_dir),
2546                 "--only-verify-expectations",
2547               ]
2548        if (defined(invoker.expected_android_manifest_base)) {
2549          args += [
2550            "--expected-file-base",
2551            rebase_path(invoker.expected_android_manifest_base, root_build_dir),
2552          ]
2553          inputs += [ invoker.expected_android_manifest_base ]
2554        }
2555        if (defined(invoker.expected_android_manifest_version_code_offset)) {
2556          args += [
2557            "--verification-version-code-offset",
2558            invoker.expected_android_manifest_version_code_offset,
2559          ]
2560        }
2561        if (defined(invoker.expected_android_manifest_library_version_offset)) {
2562          args += [
2563            "--verification-library-version-offset",
2564            invoker.expected_android_manifest_library_version_offset,
2565          ]
2566        }
2567        if (fail_on_android_expectations) {
2568          args += [ "--fail-on-expectations" ]
2569        }
2570      }
2571      _deps += [ ":$_expectations_target" ]
2572    }
2573
2574    action_with_pydeps(target_name) {
2575      script = _script
2576      depfile = "$target_gen_dir/${target_name}.d"
2577      inputs = _inputs
2578      outputs = _outputs
2579      deps = _deps
2580      args = _args + [
2581               "--depfile",
2582               rebase_path(depfile, root_build_dir),
2583             ]
2584    }
2585  }
2586
2587  # A template that is used to optimize compiled resources using aapt2 optimize.
2588  #
2589  #   proto_input_path:
2590  #     Path to input compiled .proto.ap_ file.
2591  #
2592  #   short_resource_paths: (optional)
2593  #     Rename the paths within a the apk to be randomly generated short
2594  #     strings to reduce binary size.
2595  #
2596  #   strip_resource_names: (optional)
2597  #     Strip resource names from the resources table of the apk.
2598  #
2599  #   resources_configs_paths: (optional)
2600  #     List of resource configs to use for optimization.
2601  #
2602  #   optimized_proto_output:
2603  #     Path to output optimized .proto.ap_ file.
2604  #
2605  #   resources_path_map_out_path: (optional):
2606  #       Path for the generated map between original resource paths and
2607  #       shortened resource paths.
2608  template("optimize_resources") {
2609    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
2610    action_with_pydeps(target_name) {
2611      forward_variables_from(invoker, [ "deps" ])
2612      script = "//build/android/gyp/optimize_resources.py"
2613      inputs = [
2614        android_sdk_tools_bundle_aapt2,
2615        invoker.r_text_path,
2616      ]
2617      outputs = []
2618      args = [
2619        "--aapt2-path",
2620        rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir),
2621        "--r-text-in",
2622        rebase_path(invoker.r_text_path, root_build_dir),
2623      ]
2624      if (defined(invoker.optimized_proto_output)) {
2625        inputs += [ invoker.proto_input_path ]
2626        outputs += [ invoker.optimized_proto_output ]
2627        args += [
2628          "--input-path",
2629          rebase_path(invoker.proto_input_path, root_build_dir),
2630          "--optimized-output-path",
2631          rebase_path(invoker.optimized_proto_output, root_build_dir),
2632        ]
2633      } else {
2634        inputs += [ invoker.arsc_input_path ]
2635        outputs += [ invoker.optimized_arsc_output ]
2636        args += [
2637          "--input-path",
2638          rebase_path(invoker.arsc_input_path, root_build_dir),
2639          "--optimized-output-path",
2640          rebase_path(invoker.optimized_arsc_output, root_build_dir),
2641        ]
2642      }
2643
2644      if (defined(invoker.resources_config_paths)) {
2645        inputs += invoker.resources_config_paths
2646        _rebased_resource_configs =
2647            rebase_path(invoker.resources_config_paths, root_build_dir)
2648        args += [ "--resources-config-paths=${_rebased_resource_configs}" ]
2649      }
2650
2651      if (defined(invoker.short_resource_paths) &&
2652          invoker.short_resource_paths) {
2653        args += [ "--short-resource-paths" ]
2654        if (defined(invoker.resources_path_map_out_path)) {
2655          outputs += [ invoker.resources_path_map_out_path ]
2656          args += [
2657            "--resources-path-map-out-path",
2658            rebase_path(invoker.resources_path_map_out_path, root_build_dir),
2659          ]
2660        }
2661      }
2662
2663      if (defined(invoker.strip_resource_names) &&
2664          invoker.strip_resource_names) {
2665        args += [ "--strip-resource-names" ]
2666      }
2667    }
2668  }
2669
2670  # A template that is used to find unused resources.
2671  template("unused_resources") {
2672    action_with_pydeps(target_name) {
2673      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
2674      script = "//build/android/gyp/unused_resources.py"
2675      depfile = "$target_gen_dir/${target_name}.d"
2676      _unused_resources_script = "$root_build_dir/bin/helper/unused_resources"
2677      inputs = [ _unused_resources_script ] + java_paths_for_inputs
2678      outputs = [ invoker.output_config ]
2679      if (!defined(deps)) {
2680        deps = []
2681      }
2682      deps += [ "//build/android/unused_resources:unused_resources" ]
2683      _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
2684      args = [
2685        "--script",
2686        rebase_path(_unused_resources_script, root_build_dir),
2687        "--output-config",
2688        rebase_path(invoker.output_config, root_build_dir),
2689        "--r-text-in=@FileArg($_rebased_build_config:deps_info:r_text_path)",
2690        "--dependencies-res-zips=@FileArg($_rebased_build_config:deps_info:dependency_zips)",
2691        "--depfile",
2692        rebase_path(depfile, root_build_dir),
2693      ]
2694
2695      if (defined(invoker.proguard_mapping_path)) {
2696        inputs += [ invoker.proguard_mapping_path ]
2697        args += [
2698          "--proguard-mapping",
2699          rebase_path(invoker.proguard_mapping_path, root_build_dir),
2700        ]
2701      }
2702
2703      if (defined(invoker.output_r_txt)) {
2704        outputs += [ invoker.output_r_txt ]
2705        args += [
2706          "--r-text-out",
2707          rebase_path(invoker.output_r_txt, root_build_dir),
2708        ]
2709      }
2710
2711      if (defined(invoker.all_module_build_configs)) {
2712        foreach(_build_config, invoker.all_module_build_configs) {
2713          inputs += [ _build_config ]
2714          _rebased_module_build_config =
2715              rebase_path(_build_config, root_build_dir)
2716          args += [
2717            "--dexes=@FileArg($_rebased_module_build_config:final_dex:path)",
2718            "--android-manifests=@FileArg($_rebased_module_build_config:deps_info:merged_android_manifest)",
2719          ]
2720        }
2721      } else {
2722        args += [
2723          "--dexes=@FileArg($_rebased_build_config:final_dex:path)",
2724          "--android-manifests=@FileArg($_rebased_build_config:deps_info:merged_android_manifest)",
2725        ]
2726      }
2727    }
2728  }
2729
2730  # Create an .jar.info file by merging several .jar.info files into one.
2731  #
2732  # Variables:
2733  #   build_config: Path to APK's build config file. Used to extract the
2734  #       list of input .jar files from its dependencies.
2735  #   name: Name of the apk or app bundle (e.g. "Foo.apk").
2736  #   res_size_info_path: Path to input .ap_.info file (for apks).
2737  #
2738  template("create_size_info_files") {
2739    action_with_pydeps(target_name) {
2740      forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ])
2741      script = "//build/android/gyp/create_size_info_files.py"
2742      _jar_info_path = "$root_build_dir/size-info/${invoker.name}.jar.info"
2743      _pak_info_path = "$root_build_dir/size-info/${invoker.name}.pak.info"
2744      _res_info_path = "$root_build_dir/size-info/${invoker.name}.res.info"
2745      outputs = [
2746        _jar_info_path,
2747        _pak_info_path,
2748        _res_info_path,
2749      ]
2750      depfile = "$target_gen_dir/$target_name.d"
2751      args = [
2752        "--depfile",
2753        rebase_path(depfile, root_build_dir),
2754        "--jar-info-path",
2755        rebase_path(_jar_info_path, root_build_dir),
2756        "--pak-info-path",
2757        rebase_path(_pak_info_path, root_build_dir),
2758        "--res-info-path",
2759        rebase_path(_res_info_path, root_build_dir),
2760      ]
2761      _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
2762      inputs = [ invoker.build_config ]
2763      _is_bundle = defined(invoker.modules)
2764      if (_is_bundle) {
2765        foreach(_module, invoker.modules) {
2766          inputs += [ _module.build_config ]
2767          _rebased_module_build_config =
2768              rebase_path(_module.build_config, root_build_dir)
2769          args += [
2770            "--jar-files=@FileArg($_rebased_module_build_config:deps_info:unprocessed_jar_path)",
2771            "--jar-files=@FileArg($_rebased_module_build_config:deps_info:javac_full_classpath)",
2772            "--in-res-info-path=@FileArg($_rebased_module_build_config:deps_info:res_size_info)",
2773            "--uncompressed-assets=@FileArg($_rebased_module_build_config:deps_info:uncompressed_assets)",
2774            "--assets=@FileArg($_rebased_build_config:modules:${_module.name}:assets)",
2775          ]
2776        }
2777      } else {
2778        inputs += [ invoker.res_size_info_path ]
2779        args += [
2780          "--jar-files=@FileArg($_rebased_build_config:deps_info:unprocessed_jar_path)",
2781          "--jar-files=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)",
2782          "--in-res-info-path",
2783          rebase_path(invoker.res_size_info_path, root_build_dir),
2784          "--assets=@FileArg($_rebased_build_config:deps_info:assets)",
2785          "--uncompressed-assets=@FileArg($_rebased_build_config:deps_info:uncompressed_assets)",
2786        ]
2787      }
2788    }
2789  }
2790
2791  # Creates a signed and aligned .apk.
2792  #
2793  # Variables
2794  #   apk_name: (optional) APK name (without .apk suffix). If provided, will
2795  #       be used to generate .info files later used by the supersize tool.
2796  #   assets_build_config: Path to android_apk .build_config.json containing merged
2797  #       asset information.
2798  #   deps: Specifies the dependencies of this target.
2799  #   dex_path: Path to classes.dex file to include (optional).
2800  #   expected_libs_and_assets: Verify the list of included native libraries
2801  #     and assets is consistent with the given expectation file.
2802  #   expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff
2803  #     with this file as the base.
2804  #   packaged_resources_path: Path to .ap_ to use.
2805  #   output_apk_path: Output path for the generated .apk.
2806  #   min_sdk_version: The minimum Android SDK version this target supports.
2807  #   native_lib_placeholders: List of placeholder filenames to add to the apk
2808  #     (optional).
2809  #   secondary_native_lib_placeholders: List of placeholder filenames to add to
2810  #     the apk for the secondary ABI (optional).
2811  #   loadable_modules: List of native libraries.
2812  #   native_libs_filearg: @FileArg() of additionally native libraries.
2813  #   secondary_abi_loadable_modules: (optional) List of native libraries for
2814  #     secondary ABI.
2815  #   secondary_abi_native_libs_filearg: (optional). @FileArg() of additional
2816  #     secondary ABI native libs.
2817  #   keystore_path: Path to keystore to use for signing.
2818  #   keystore_name: Key alias to use.
2819  #   keystore_password: Keystore password.
2820  template("package_apk") {
2821    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "public_deps" ])
2822    _is_robolectric_apk =
2823        defined(invoker.is_robolectric_apk) && invoker.is_robolectric_apk
2824    _deps = invoker.deps
2825    _native_lib_placeholders = []
2826    if (defined(invoker.native_lib_placeholders)) {
2827      _native_lib_placeholders = invoker.native_lib_placeholders
2828    }
2829    _secondary_native_lib_placeholders = []
2830    if (defined(invoker.secondary_native_lib_placeholders)) {
2831      _secondary_native_lib_placeholders =
2832          invoker.secondary_native_lib_placeholders
2833    }
2834
2835    _script = "//build/android/gyp/apkbuilder.py"
2836
2837    _inputs = [ invoker.packaged_resources_path ]
2838
2839    _outputs = [ invoker.output_apk_path ]
2840    _data = [ invoker.output_apk_path ]
2841
2842    _rebased_compiled_resources_path =
2843        rebase_path(invoker.packaged_resources_path, root_build_dir)
2844    _rebased_packaged_apk_path =
2845        rebase_path(invoker.output_apk_path, root_build_dir)
2846    _args = [
2847      "--resource-apk=$_rebased_compiled_resources_path",
2848      "--output-apk=$_rebased_packaged_apk_path",
2849      "--min-sdk-version=${invoker.min_sdk_version}",
2850    ]
2851
2852    # system_image_stub_apk does not use a build_config.json.
2853    if (defined(invoker.build_config)) {
2854      _inputs += [ invoker.build_config ]
2855      _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
2856      _args += [
2857        "--assets=@FileArg($_rebased_build_config:deps_info:assets)",
2858        "--uncompressed-assets=@FileArg($_rebased_build_config:deps_info:uncompressed_assets)",
2859      ]
2860      if (!_is_robolectric_apk) {
2861        _args += [ "--java-resources=@FileArg($_rebased_build_config:java_resources_jars)" ]
2862      }
2863    }
2864    if (defined(invoker.extra_assets)) {
2865      _args += [ "--assets=${invoker.extra_assets}" ]
2866    }
2867    if (!_is_robolectric_apk) {
2868      _apksigner = "$android_sdk_build_tools/lib/apksigner.jar"
2869      _zipalign = "$android_sdk_build_tools/zipalign"
2870      _keystore_path = android_keystore_path
2871      _keystore_name = android_keystore_name
2872      _keystore_password = android_keystore_password
2873
2874      if (defined(invoker.keystore_path)) {
2875        _keystore_path = invoker.keystore_path
2876        _keystore_name = invoker.keystore_name
2877        _keystore_password = invoker.keystore_password
2878      }
2879
2880      _inputs += [
2881        _apksigner,
2882        _zipalign,
2883        _keystore_path,
2884      ]
2885      _args += [
2886        "--apksigner-jar",
2887        rebase_path(_apksigner, root_build_dir),
2888        "--zipalign-path",
2889        rebase_path(_zipalign, root_build_dir),
2890        "--key-path",
2891        rebase_path(_keystore_path, root_build_dir),
2892        "--key-name",
2893        _keystore_name,
2894        "--key-passwd",
2895        _keystore_password,
2896      ]
2897      if (is_official_build) {
2898        _args += [ "--best-compression" ]
2899      }
2900    }
2901    if (defined(invoker.uncompress_dex)) {
2902      _uncompress_dex = invoker.uncompress_dex
2903    } else {
2904      # Uncompressed dex support started on Android P.
2905      _uncompress_dex = invoker.min_sdk_version >= 28
2906    }
2907
2908    if (_uncompress_dex) {
2909      _args += [ "--uncompress-dex" ]
2910    }
2911    if (defined(invoker.library_always_compress)) {
2912      _args +=
2913          [ "--library-always-compress=${invoker.library_always_compress}" ]
2914    }
2915    if (defined(invoker.dex_path)) {
2916      _inputs += [ invoker.dex_path ]
2917      _args += [
2918        "--dex-file",
2919        rebase_path(invoker.dex_path, root_build_dir),
2920      ]
2921    }
2922    if ((defined(invoker.loadable_modules) && invoker.loadable_modules != []) ||
2923        defined(invoker.native_libs_filearg) ||
2924        _native_lib_placeholders != []) {
2925      _args += [ "--android-abi=$android_app_abi" ]
2926    }
2927    if (defined(android_app_secondary_abi)) {
2928      _args += [ "--secondary-android-abi=$android_app_secondary_abi" ]
2929    }
2930    if (defined(invoker.loadable_modules) && invoker.loadable_modules != []) {
2931      _inputs += invoker.loadable_modules
2932      _rebased_loadable_modules =
2933          rebase_path(invoker.loadable_modules, root_build_dir)
2934      _args += [ "--native-libs=$_rebased_loadable_modules" ]
2935    }
2936    if (defined(invoker.native_libs_filearg)) {
2937      _args += [ "--native-libs=${invoker.native_libs_filearg}" ]
2938    }
2939    if (_native_lib_placeholders != []) {
2940      _args += [ "--native-lib-placeholders=$_native_lib_placeholders" ]
2941    }
2942
2943    if (defined(invoker.secondary_abi_native_libs_filearg)) {
2944      _args += [
2945        "--secondary-native-libs=${invoker.secondary_abi_native_libs_filearg}",
2946      ]
2947    }
2948    if (defined(invoker.secondary_abi_loadable_modules)) {
2949      _inputs += invoker.secondary_abi_loadable_modules
2950      _rebased_secondary_abi_loadable_modules =
2951          rebase_path(invoker.secondary_abi_loadable_modules, root_build_dir)
2952      _args +=
2953          [ "--secondary-native-libs=$_rebased_secondary_abi_loadable_modules" ]
2954    }
2955    if (_secondary_native_lib_placeholders != []) {
2956      _args += [ "--secondary-native-lib-placeholders=$_secondary_native_lib_placeholders" ]
2957    }
2958    if (treat_warnings_as_errors) {
2959      _args += [ "--warnings-as-errors" ]
2960    }
2961
2962    if (defined(invoker.expected_libs_and_assets)) {
2963      _expectations_target =
2964          "${invoker.top_target_name}_validate_libs_and_assets"
2965      action_with_pydeps(_expectations_target) {
2966        _actual_file = "$target_gen_dir/$target_name.libs_and_assets"
2967        _failure_file =
2968            "$expectations_failure_dir/" +
2969            string_replace(invoker.expected_libs_and_assets, "/", "_")
2970        inputs = [ invoker.expected_libs_and_assets ]
2971        if (defined(invoker.build_config)) {
2972          inputs += [ invoker.build_config ]
2973        }
2974        deps = [ invoker.build_config_dep ]
2975        outputs = [
2976          _actual_file,
2977          _failure_file,
2978        ]
2979        script = _script
2980        args = _args + [
2981                 "--expected-file",
2982                 rebase_path(invoker.expected_libs_and_assets, root_build_dir),
2983                 "--actual-file",
2984                 rebase_path(_actual_file, root_build_dir),
2985                 "--failure-file",
2986                 rebase_path(_failure_file, root_build_dir),
2987                 "--only-verify-expectations",
2988               ]
2989        if (defined(invoker.expected_libs_and_assets_base)) {
2990          inputs += [ invoker.expected_libs_and_assets_base ]
2991          args += [
2992            "--expected-file-base",
2993            rebase_path(invoker.expected_libs_and_assets_base, root_build_dir),
2994          ]
2995        }
2996        if (fail_on_android_expectations) {
2997          args += [ "--fail-on-expectations" ]
2998        }
2999      }
3000      _deps += [ ":$_expectations_target" ]
3001    }
3002    action_with_pydeps(target_name) {
3003      depfile = "$target_gen_dir/$target_name.d"
3004      inputs = _inputs
3005      deps = _deps
3006      data = _data
3007      outputs = _outputs
3008      script = _script
3009      args = _args + [
3010               "--depfile",
3011               rebase_path(depfile, root_build_dir),
3012             ]
3013    }
3014  }
3015
3016  # Compile Java source files into a .jar file, potentially using an
3017  # annotation processor, and/or the errorprone compiler. Also includes Kotlin
3018  # source files in the resulting info file.
3019  #
3020  # Note that the only way to specify custom annotation processors is
3021  # by using build_config to point to a file that corresponds to a java-related
3022  # target that includes javac:processor_classes entries (i.e. there is no
3023  # variable here that can be used for this purpose).
3024  #
3025  # Note also the peculiar use of source_files / target_sources_file. The content
3026  # of the source_files list and the source files in target_sources_file file must
3027  # match exactly.
3028  #
3029  # Variables:
3030  #  main_target_name: Used when extracting srcjars for codesearch.
3031  #  source_files: Optional list of Java and Kotlin source file paths.
3032  #  srcjar_deps: Optional list of .srcjar dependencies (not file paths).
3033  #    The corresponding source files they contain will be compiled too.
3034  #  target_sources_file: Optional path to file containing list of source file
3035  #    paths. This must always be provided if java_files is not empty and the
3036  #    .java files in it must match the list of java_files exactly.
3037  #  build_config: Path to the .build_config.json file of the corresponding
3038  #    java_library_impl() target. The following entries will be used by this
3039  #    template: javac:srcjars, deps_info:javac_full_classpath,
3040  #    deps_info:javac_full_interface_classpath, javac:processor_classpath,
3041  #    javac:processor_classes
3042  #  javac_jar_path: Path to the final output .jar file.
3043  #  javac_args: Optional list of extra arguments to pass to javac.
3044  #  chromium_code: Whether this corresponds to Chromium-specific sources.
3045  #  requires_android: True if these sources can only run on Android.
3046  #  additional_jar_files: Optional list of files to copy into the resulting
3047  #    .jar file (by default, only .class files are put there). Each entry
3048  #    has the 'srcPath:dstPath' format.
3049  #  enable_errorprone: If True, use the errorprone compiler to check for
3050  #    error-prone constructs in the language. If not provided, whether this is
3051  #    enabled depends on chromium_code and the global
3052  #    use_errorprone_java_compiler variable.
3053  #  use_turbine: If True, compile headers using turbine.py.
3054  #  apk_name: Optional APK name. If provided, will tell compile_java.py to also
3055  #    generate an .apk.jar.info file under size-info/${apk_name}.apk.jar.info
3056  #  processor_args_javac: List of annotation processor arguments, each one
3057  #    will be passed to javac as -A<entry>.
3058  #  deps: Dependencies for the corresponding target.
3059  #  testonly: Usual meaning (should be True for test-only targets)
3060  #
3061  # [1] https://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html
3062  #
3063  template("compile_java") {
3064    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
3065
3066    _build_config = invoker.build_config
3067    _chromium_code = invoker.chromium_code
3068
3069    _processor_args = []
3070    if (defined(invoker.processor_args_javac)) {
3071      _processor_args = invoker.processor_args_javac
3072    }
3073
3074    _additional_jar_files = []
3075    if (defined(invoker.additional_jar_files)) {
3076      _additional_jar_files = invoker.additional_jar_files
3077    }
3078
3079    _srcjar_deps = []
3080    if (defined(invoker.srcjar_deps)) {
3081      _srcjar_deps = invoker.srcjar_deps
3082    }
3083
3084    if (!invoker.enable_errorprone) {
3085      _java_srcjars = []
3086      foreach(dep, _srcjar_deps) {
3087        _dep_gen_dir = get_label_info(dep, "target_gen_dir")
3088        _dep_name = get_label_info(dep, "name")
3089        _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ]
3090      }
3091      if (defined(invoker.srcjars)) {
3092        _java_srcjars += invoker.srcjars
3093      }
3094
3095      # generated_jar_path is an output when use_turbine and an input otherwise.
3096      if (!invoker.use_turbine && defined(invoker.generated_jar_path)) {
3097        _java_srcjars += [ invoker.generated_jar_path ]
3098      }
3099    }
3100
3101    _javac_args = []
3102    if (defined(invoker.javac_args)) {
3103      _javac_args = invoker.javac_args
3104    }
3105
3106    action_with_pydeps(target_name) {
3107      if (invoker.use_turbine) {
3108        script = "//build/android/gyp/turbine.py"
3109        inputs = [
3110          "//third_party/jdk/current/bin/java",
3111          android_sdk_jar,
3112        ]
3113      } else if (invoker.enable_errorprone) {
3114        script = "//build/android/gyp/errorprone.py"
3115        inputs = javac_paths_for_inputs
3116      } else {
3117        script = "//build/android/gyp/compile_java.py"
3118        inputs = javac_paths_for_inputs
3119      }
3120
3121      if (target_name == "chrome_java__header") {
3122        # Regression test for: https://crbug.com/1154302
3123        # Ensures that header jars never depend on non-header jars.
3124        assert_no_deps = [ "//base:base_java__compile_java" ]
3125      }
3126
3127      depfile = "$target_gen_dir/$target_name.d"
3128      deps = _srcjar_deps
3129      if (defined(invoker.deps)) {
3130        deps += invoker.deps
3131      }
3132
3133      args = []
3134      if (invoker.enable_errorprone) {
3135        _stamp_file = "$target_out_dir/$target_name.stamp"
3136        outputs = [ _stamp_file ]
3137        _rebased_stamp_file = rebase_path(_stamp_file, root_build_dir)
3138        args += [ "--stamp=$_rebased_stamp_file" ]
3139      } else {
3140        outputs = [ invoker.output_jar_path ]
3141        if (!invoker.use_turbine) {
3142          outputs += [ invoker.output_jar_path + ".info" ]
3143        }
3144        _rebased_output_jar_path =
3145            rebase_path(invoker.output_jar_path, root_build_dir)
3146
3147        # Error Prone does not run on srcjar, and they are not needed as inputs thanks to Turbine.
3148        _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir)
3149        _rebased_generated_dir = rebase_path(
3150                "$target_gen_dir/${invoker.main_target_name}/generated_java",
3151                root_build_dir)
3152        args += [
3153          "--jar-path=$_rebased_output_jar_path",
3154          "--java-srcjars=$_rebased_java_srcjars",
3155          "--generated-dir=$_rebased_generated_dir",
3156        ]
3157        inputs += _java_srcjars
3158      }
3159      inputs += invoker.source_files + [
3160                  "$android_sdk/optional/android.test.base.jar",
3161                  "$android_sdk/optional/org.apache.http.legacy.jar",
3162                  _build_config,
3163                ] + java_paths_for_inputs
3164
3165      if (invoker.source_files != []) {
3166        inputs += [ invoker.target_sources_file ]
3167      }
3168
3169      _rebased_build_config = rebase_path(_build_config, root_build_dir)
3170      _rebased_depfile = rebase_path(depfile, root_build_dir)
3171      args += [
3172        "--depfile=$_rebased_depfile",
3173        "--target-name",
3174        get_label_info(":${target_name}", "label_no_toolchain"),
3175      ]
3176
3177      # SDK jar must be first on classpath.
3178      if (invoker.include_android_sdk) {
3179        args += [ "--classpath=@FileArg($_rebased_build_config:android:sdk_interface_jars)" ]
3180      }
3181
3182      if (defined(invoker.header_jar_path)) {
3183        inputs += [ invoker.header_jar_path ]
3184        args += [
3185          "--header-jar",
3186          rebase_path(invoker.header_jar_path, root_build_dir),
3187        ]
3188        _header_jar_classpath =
3189            [ rebase_path(invoker.header_jar_path, root_build_dir) ]
3190        args += [ "--classpath=$_header_jar_classpath" ]
3191      }
3192
3193      if (defined(invoker.kotlin_jar_path)) {
3194        inputs += [ invoker.kotlin_jar_path ]
3195        _rebased_kotlin_jar_path =
3196            rebase_path(invoker.kotlin_jar_path, root_build_dir)
3197        args += [
3198          "--kotlin-jar-path=$_rebased_kotlin_jar_path",
3199          "--classpath=$_rebased_kotlin_jar_path",
3200        ]
3201      }
3202
3203      if (invoker.use_turbine) {
3204        # Prefer direct deps for turbine as much as possible.
3205        args += [ "--classpath=@FileArg($_rebased_build_config:javac:interface_classpath)" ]
3206      } else {
3207        args += [ "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)" ]
3208      }
3209
3210      if (invoker.use_turbine) {
3211        args += [
3212          "--processorpath=@FileArg($_rebased_build_config:javac:processor_classpath)",
3213          "--processors=@FileArg($_rebased_build_config:javac:processor_classes)",
3214        ]
3215      }
3216
3217      if (invoker.use_turbine) {
3218        _turbine_jar_path = "//third_party/turbine/cipd/turbine.jar"
3219        inputs += [ _turbine_jar_path ]
3220        outputs += [ invoker.generated_jar_path ]
3221        args += [
3222          "--turbine-jar-path",
3223          rebase_path(_turbine_jar_path, root_build_dir),
3224          "--generated-jar-path",
3225          rebase_path(invoker.generated_jar_path, root_build_dir),
3226        ]
3227      }
3228
3229      # Flag enable_kythe_annotations requires
3230      # checkout_android_prebuilts_build_tools=True in .gclient.
3231      if (enable_kythe_annotations && !invoker.enable_errorprone) {
3232        args += [ "--enable-kythe-annotations" ]
3233      }
3234      if (_chromium_code) {
3235        args += [ "--chromium-code" ]
3236        if (treat_warnings_as_errors) {
3237          args += [ "--warnings-as-errors" ]
3238        }
3239      }
3240      if (defined(invoker.jar_excluded_patterns)) {
3241        args += [ "--jar-info-exclude-globs=${invoker.jar_excluded_patterns}" ]
3242      }
3243      if (defined(invoker.jar_included_patterns)) {
3244        args += [ "--jar-info-include-globs=${invoker.jar_included_patterns}" ]
3245      }
3246
3247      if (invoker.enable_errorprone) {
3248        # Our custom plugin pulls in the main errorprone dep transitively.
3249        _errorprone_dep = "//tools/android/errorprone_plugin:errorprone_plugin"
3250        deps += [ _errorprone_dep ]
3251        _dep_gen_dir = get_label_info(_errorprone_dep, "target_gen_dir")
3252        _dep_name = get_label_info(_errorprone_dep, "name")
3253        _rebased_errorprone_buildconfig =
3254            rebase_path("$_dep_gen_dir/$_dep_name.build_config.json",
3255                        root_build_dir)
3256        args += [ "--processorpath=@FileArg($_rebased_errorprone_buildconfig:deps_info:host_classpath)" ]
3257        inputs += [
3258          # errorprone requires the plugin directory to detect src dir.
3259          # https://source.chromium.org/chromium/chromium/src/+/main:tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java;l=84;drc=dfd88085261b662a5c0a1abea1a3b120b08e8e48
3260          "//tools/android/errorprone_plugin/OWNERS",
3261        ]
3262        if (defined(testonly) && testonly) {
3263          args += [ "--testonly" ]
3264        } else {
3265          inputs += [ _nullaway_jar ]
3266          args += [
3267            "--processorpath=$_rebased_nullaway_jar",
3268            "--enable-nullaway",
3269          ]
3270        }
3271        if (defined(invoker.skip_build_server) && invoker.skip_build_server) {
3272          # Nocompile tests need lint to fail through ninja.
3273          args += [ "--skip-build-server" ]
3274        } else if (android_static_analysis == "build_server") {
3275          args += [ "--use-build-server" ]
3276        }
3277      }
3278
3279      foreach(e, _processor_args) {
3280        args += [ "--processor-arg=" + e ]
3281      }
3282
3283      foreach(file_tuple, _additional_jar_files) {
3284        # Each element is of length two, [ path_to_file, path_to_put_in_jar ]
3285        inputs += [ file_tuple[0] ]
3286        args +=
3287            [ "--additional-jar-file=" +
3288              rebase_path(file_tuple[0], root_build_dir) + ":" + file_tuple[1] ]
3289      }
3290      if (invoker.source_files != []) {
3291        args +=
3292            [ "@" + rebase_path(invoker.target_sources_file, root_build_dir) ]
3293      }
3294      foreach(e, _javac_args) {
3295        args += [ "--javac-arg=" + e ]
3296      }
3297    }
3298  }
3299
3300  # Compile Kotlin source files into .class files and store them in a .jar.
3301  # This explicitly does not run annotation processing on the Kotlin files.
3302  # Java files and srcjars are also passed to kotlinc for reference, although
3303  # no .class files will be generated for any Java files. A subsequent call to
3304  # javac will be required to actually compile Java files into .class files.
3305  #
3306  # This action also creates a "header" .jar file for the Kotlin source files.
3307  # It is similar to using turbine to create headers for Java files, but since
3308  # turbine does not support Kotlin files, this is done via a plugin for
3309  # kotlinc instead, at the same time as compilation (whereas turbine is run as
3310  # a separate action before javac compilation).
3311  template("compile_kt") {
3312    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
3313
3314    _build_config = invoker.build_config
3315    _chromium_code = invoker.chromium_code
3316
3317    _srcjar_deps = []
3318    if (defined(invoker.srcjar_deps)) {
3319      _srcjar_deps = invoker.srcjar_deps
3320    }
3321
3322    _java_srcjars = []
3323    foreach(dep, _srcjar_deps) {
3324      _dep_gen_dir = get_label_info(dep, "target_gen_dir")
3325      _dep_name = get_label_info(dep, "name")
3326      _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ]
3327    }
3328
3329    if (defined(invoker.srcjars)) {
3330      _java_srcjars += invoker.srcjars
3331    }
3332
3333    action_with_pydeps(target_name) {
3334      script = "//build/android/gyp/compile_kt.py"
3335      depfile = "$target_gen_dir/$target_name.d"
3336      deps = _srcjar_deps
3337      if (defined(invoker.deps)) {
3338        deps += invoker.deps
3339      }
3340
3341      outputs = [
3342        invoker.output_jar_path,
3343        invoker.output_interface_jar_path,
3344      ]
3345      inputs = kotlinc_paths_for_inputs + java_paths_for_inputs +
3346               invoker.source_files + _java_srcjars +
3347               [
3348                 _build_config,
3349                 invoker.target_sources_file,
3350               ]
3351
3352      _rebased_build_config = rebase_path(_build_config, root_build_dir)
3353      _rebased_output_jar_path =
3354          rebase_path(invoker.output_jar_path, root_build_dir)
3355      _rebased_output_interface_jar_path =
3356          rebase_path(invoker.output_interface_jar_path, root_build_dir)
3357      _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir)
3358      _rebased_depfile = rebase_path(depfile, root_build_dir)
3359      _rebased_generated_dir = rebase_path(
3360              "$target_gen_dir/${invoker.main_target_name}/generated_java",
3361              root_build_dir)
3362      args = [
3363        "--depfile=$_rebased_depfile",
3364        "--generated-dir=$_rebased_generated_dir",
3365        "--jar-path=$_rebased_output_jar_path",
3366        "--interface-jar-path=$_rebased_output_interface_jar_path",
3367        "--java-srcjars=$_rebased_java_srcjars",
3368      ]
3369
3370      # SDK jar must be first on classpath.
3371      if (invoker.include_android_sdk) {
3372        args += [ "--classpath=@FileArg($_rebased_build_config:android:sdk_interface_jars)" ]
3373      }
3374
3375      args += [ "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)" ]
3376
3377      if (_chromium_code) {
3378        args += [ "--chromium-code" ]
3379        if (treat_warnings_as_errors) {
3380          args += [ "--warnings-as-errors" ]
3381        }
3382      }
3383
3384      args += [ "@" + rebase_path(invoker.target_sources_file, root_build_dir) ]
3385    }
3386  }
3387
3388  # Create an interface jar from a normal jar.
3389  #
3390  # Variables
3391  #   input_jar: Path to input .jar.
3392  #   output_jar: Path to output .ijar.
3393  #
3394  template("generate_interface_jar") {
3395    action_with_pydeps(target_name) {
3396      _ijar_target = "//third_party/ijar:ijar($host_toolchain)"
3397      _ijar_executable = get_label_info(_ijar_target, "root_out_dir") + "/ijar"
3398      forward_variables_from(invoker,
3399                             TESTONLY_AND_VISIBILITY + [
3400                                   "data",
3401                                   "data_deps",
3402                                   "public_deps",
3403                                 ])
3404      script = "//build/android/gyp/ijar.py"
3405      deps = [ _ijar_target ]
3406      if (defined(invoker.deps)) {
3407        deps += invoker.deps
3408      }
3409      inputs = [
3410        invoker.input_jar,
3411        _ijar_executable,
3412      ]
3413      if (defined(invoker.inputs)) {
3414        inputs += invoker.inputs
3415      }
3416      outputs = [ invoker.output_jar ]
3417      args = [
3418        rebase_path(_ijar_executable, root_build_dir),
3419        rebase_path(invoker.input_jar, root_build_dir),
3420        rebase_path(invoker.output_jar, root_build_dir),
3421      ]
3422    }
3423  }
3424
3425  # A rule that will handle multiple Java-related targets.
3426  #
3427  # The caller can provide a list of source files with 'java_files'
3428  # and 'srcjar_deps', or a prebuilt .jar file through 'jar_path'.
3429  #
3430  # In the case of a 'java_binary' target type, it can even provide none of
3431  # that (and the rule will just generate its wrapper script).
3432  #
3433  # The template will process the input .jar file (either the prebuilt one,
3434  # or the result of compiling the sources), for example to apply Proguard,
3435  # but also other ranges of bytecode-level rewriting schemes.
3436  #
3437  # Variables:
3438  #  type: type of Java target, valid values: 'java_library', 'java_binary',
3439  #    'robolectric_binary', 'java_annotation_processor', and 'android_apk'
3440  #  main_target_name: optional. If provided, overrides target_name when
3441  #    creating sub-targets (e.g. "${main_target_name}__dex") and
3442  #    some output files (e.g. "${main_target_name}.sources"). Only used
3443  #    for 'android_apk' types at the moment, where main_target_name will
3444  #    be the name of the main APK target.
3445  #  supports_android: Optional. True if target can run on Android.
3446  #  requires_android: Optional. True if target can only run on Android.
3447  #  source_files: Optional list of Java source file paths for this target.
3448  #  javac_args: Optional list of extra arguments to pass to javac.
3449  #  errorprone_args: Optional list of extra arguments to pass to.
3450  #  srcjar_deps: Optional list of .srcjar targets (not file paths). The Java
3451  #    source files they contain will also be compiled for this target.
3452  #  target_sources_file: Optional path to a file which will be written with
3453  #    the content of source_files. If not provided, the file will be written
3454  #    under $target_gen_dir/$main_target_name.sources. Ignored if
3455  #    sources_files is empty. If not
3456  #  jar_path: Optional path to a prebuilt .jar file for this target.
3457  #    Mutually exclusive with java_files and srcjar_deps.
3458  #  output_name: Optional output name for the final jar path. Used to
3459  #    determine the name of the final jar. Default is to use the same
3460  #    name as jar_path, if provided, or main_target_name.
3461  #  main_class: Main Java class name for 'java_binary', 'robolectric_binary' and
3462  #    'java_annotation_processor' target types. Should not be set for other
3463  #    ones.
3464  #  deps: Dependencies for this target.
3465  #  public_deps: Dependencies that this target exposes as part of its public API.
3466  #    public_deps do not need to be listed in both the 'deps' and 'public_deps' lists.
3467  #  testonly: True iff target should only be used for tests.
3468  #  chromium_code: Optional. Whether this is Chromium-specific code. If not
3469  #    provided, this is determined automatically, based on the location of
3470  #    the source files (i.e. anything under third_party/ is not
3471  #    Chromium-specific unless it is in a 'chromium' sub-directory).
3472  #  jacoco_never_instrument: Optional. If provided, whether to forbid
3473  #    instrumentation with the Jacoco coverage processor. If not provided,
3474  #    this is controlled by the global use_jacoco_coverage build arg variable
3475  #    and only used for non-test Chromium code.
3476  #  include_android_sdk: Optional. Whether or not the android SDK dep
3477  #    should be added to deps. Defaults to true for non-system libraries
3478  #    that support android.
3479  #  alternative_android_sdk_dep: Optional. Alternative Android system
3480  #    android java target to use.
3481  #  annotation_processor_deps: Optional list of dependencies corresponding
3482  #    to annotation processors used to compile these sources.
3483  #  input_jars_paths: Optional list of additional .jar file paths, which will
3484  #    be added to the compile-time classpath when building this target (but
3485  #    not to the runtime classpath).
3486  #  gradle_treat_as_prebuilt: Cause generate_gradle.py to reference this
3487  #    library via its built .jar rather than including its .java sources.
3488  #  proguard_enabled: Optional. True to enable ProGuard obfuscation.
3489  #  proguard_configs: Optional list of additional proguard config file paths.
3490  #  is_robolectric: Optional. If True, this is a host side android test binary
3491  #    which is allowed to depend on other android targets.
3492  #  include_java_resources: Optional. If True, include Java (not Android)
3493  #    resources into final .jar file.
3494  #  jar_excluded_patterns: Optional list of .class file patterns to exclude
3495  #    from the final .jar file.
3496  #  jar_included_patterns: Optional list of .class file patterns to include
3497  #    in the final .jar file. jar_excluded_patterns take precedence over this.
3498  #  low_classpath_priority: Indicates that the library should be placed at the
3499  #    end of the classpath. The default classpath order has libraries ordered
3500  #    before the libraries that they depend on. 'low_classpath_priority' is
3501  #    useful when one java_library() overrides another via
3502  #    'jar_excluded_patterns' and the overriding library does not depend on the
3503  #    overridee.
3504  #
3505  # For 'android_apk' and 'android_app_bundle_module' targets only:
3506  #
3507  #  apk_path: Path to the final APK file.
3508  #  android_manifest: Path to AndroidManifest.xml file for the APK.
3509  #  android_manifest_dep: Optional. Dependency target that generates
3510  #    android_manifest.
3511  #  apk_under_test: For 'android_apk' targets used to test other APKs,
3512  #    this is the target name of APK being tested.
3513  #  incremental_apk_path: Path to the incremental APK.
3514  #  incremental_install_json_path: Path to the incremental install json.
3515  #  native_lib_placeholders: Optional. List of placeholder filenames to add to
3516  #    the APK.
3517  #  proguard_mapping_path: Path to .mapping file produced from ProGuard step.
3518  #  shared_libraries_runtime_deps_file: Optional. Path to a file listing the
3519  #    native shared libraries required at runtime by the APK.
3520  #  secondary_abi_shared_libraries_runtime_deps_file:
3521  #  secondary_native_lib_placeholders: Optional. List of placeholder filenames
3522  #    to add to the APK for the secondary ABI.
3523  #  loadable_modules: Optional list of extra native libraries to
3524  #    be stored in the APK.
3525  #  secondary_abi_loadable_modules: Optional list of native libraries for
3526  #    secondary ABI.
3527  #  proto_resources_path: The path of an zip archive containing the APK's
3528  #    resources compiled to the protocol buffer format (instead of regular
3529  #    binary xml + resources.arsc).
3530  #  r_text_path: The path of the R.txt file generated when compiling the
3531  #    resources for this target.
3532  #  module_pathmap_path: The path of the pathmap file generated when compiling
3533  #    the resources for the bundle module, if path shortening is enabled.
3534  #  base_allowlist_rtxt_path: The path of the R.txt file containing the
3535  #    list of string resources to keep in the base split APK for any bundle
3536  #    that uses this target.
3537  #
3538  # For 'java_binary' and 'robolectric_binary' targets only. Ignored by others:
3539  #
3540  #  wrapper_script_name: Optional name for the generated wrapper script.
3541  #    Default is main target name.
3542  #  wrapper_script_args: Optional list of extra arguments used by the
3543  #    generated wrapper script.
3544  #
3545  template("java_library_impl") {
3546    forward_variables_from(invoker, [ "testonly" ])
3547
3548    _target_dir = get_label_info(":any_name_here", "dir")
3549
3550    _is_prebuilt = defined(invoker.jar_path)
3551    _type = invoker.type
3552    _is_annotation_processor = _type == "java_annotation_processor"
3553    _is_java_binary = _type == "java_binary" || _type == "robolectric_binary"
3554    _is_library = _type == "java_library"
3555    _supports_android =
3556        defined(invoker.supports_android) && invoker.supports_android
3557    _requires_android =
3558        defined(invoker.requires_android) && invoker.requires_android
3559    _supports_host = !_requires_android
3560    if (_is_java_binary || _is_annotation_processor) {
3561      assert(!_requires_android && !_supports_android)
3562    }
3563
3564    _bypass_platform_checks = defined(invoker.bypass_platform_checks) &&
3565                              invoker.bypass_platform_checks
3566    _is_robolectric = defined(invoker.is_robolectric) && invoker.is_robolectric
3567
3568    if (defined(invoker.sources)) {
3569      _source_files = invoker.sources
3570    } else {
3571      _source_files = []
3572    }
3573    _srcjar_deps = []
3574    if (defined(invoker.srcjar_deps)) {
3575      _srcjar_deps = invoker.srcjar_deps
3576    }
3577    _srcjars = []
3578    if (defined(invoker.srcjars)) {
3579      _srcjars = invoker.srcjars
3580    }
3581    _has_sources = _source_files != [] || _srcjar_deps != [] || _srcjars != []
3582
3583    if (defined(invoker.chromium_code)) {
3584      _chromium_code = invoker.chromium_code
3585    } else {
3586      # Default based on whether target is in third_party.
3587      _chromium_code =
3588          filter_exclude([ _target_dir ], [ "*\bthird_party\b*" ]) != []
3589      if (!_chromium_code && !_is_prebuilt && _source_files != []) {
3590        # Unless third_party code has an org.chromium file in it.
3591        _chromium_code =
3592            filter_exclude(_source_files, [ "*\bchromium\b*" ]) != _source_files
3593      }
3594    }
3595
3596    if (_chromium_code && _has_sources && _target_dir != "//build/android") {
3597      _default_deps = [ "//build/android:build_java" ]
3598    } else {
3599      _default_deps = []
3600    }
3601    _invoker_deps = _default_deps
3602    if (defined(invoker.deps)) {
3603      _invoker_deps += invoker.deps
3604    }
3605    if (defined(invoker.public_deps)) {
3606      _invoker_deps += invoker.public_deps
3607    }
3608
3609    if (_is_prebuilt || _has_sources) {
3610      # This allows us to use jar_excluded_patterns and prevent even the
3611      # interface jars from having these classes. This means that, with this
3612      # flag, nobody depending on this java library will be able to see these
3613      # classes. These excluded classes are only used for the exact target they
3614      # are compiled in. We do this by not making a header jar, and replacing
3615      # all usages of the header jar with the processed (post-exclusion) jar.
3616      _skip_header_jar =
3617          defined(invoker.prevent_excluded_classes_from_classpath) &&
3618          invoker.prevent_excluded_classes_from_classpath
3619    }
3620
3621    if (_is_prebuilt) {
3622      assert(!_has_sources)
3623    } else {
3624      # Allow java_binary to not specify any sources. This is needed when a prebuilt
3625      # is needed as a library as well as a binary.
3626      assert(_is_annotation_processor || _is_java_binary || _has_sources)
3627    }
3628
3629    if (_is_java_binary) {
3630      assert(defined(invoker.main_class), "${_type}() must set main_class")
3631    } else if (_is_annotation_processor) {
3632      assert(defined(invoker.main_class),
3633             "java_annotation_processor() must set main_class")
3634    } else {
3635      assert(!defined(invoker.main_class),
3636             "main_class cannot be used for target of type ${_type}")
3637    }
3638
3639    if (defined(invoker.main_target_name)) {
3640      _main_target_name = invoker.main_target_name
3641    } else {
3642      _main_target_name = target_name
3643    }
3644
3645    # Define build_config_deps which will be a list of targets required to
3646    # build the _build_config.
3647    _build_config = "$target_gen_dir/$_main_target_name.build_config.json"
3648    _build_config_target_name =
3649        "${_main_target_name}$build_config_target_suffix"
3650
3651    # The only target that might have no prebuilt and no sources is a java_binary.
3652    _build_host_jar = false
3653    _build_device_jar = false
3654    if (_is_prebuilt || _has_sources) {
3655      if (defined(invoker.output_name)) {
3656        _output_name = invoker.output_name
3657      } else {
3658        _output_name = _main_target_name
3659      }
3660
3661      _build_host_jar = _is_java_binary || _is_annotation_processor ||
3662                        _type == "java_library" || _type == "dist_jar"
3663      _build_device_jar = _type != "system_java_library" && _supports_android
3664
3665      _jacoco_instrument =
3666          use_jacoco_coverage && _chromium_code && _source_files != [] &&
3667          _build_device_jar && (!defined(invoker.testonly) || !invoker.testonly)
3668      if (defined(invoker.jacoco_never_instrument)) {
3669        _jacoco_instrument =
3670            !invoker.jacoco_never_instrument && _jacoco_instrument
3671      }
3672      if (_jacoco_instrument) {
3673        _invoker_deps += [ _jacoco_dep ]
3674      }
3675
3676      if (_build_host_jar) {
3677        # Jar files can be needed at runtime (by Robolectric tests or java binaries),
3678        # so do not put them under obj/.
3679        # TODO(agrieve): I suspect it would be better to use dist_jar for java_binary
3680        #     rather than archiving unnecessary .jar files within lib.java.
3681        _host_processed_jar_path =
3682            "$root_out_dir/lib.java$_target_dir/$_output_name.jar"
3683      }
3684      if (_build_device_jar) {
3685        _dex_path = "$target_out_dir/$_main_target_name.dex.jar"
3686        _enable_desugar =
3687            !defined(invoker.enable_desugar) || invoker.enable_desugar
3688
3689        # Build speed optimization: Skip "process device" step if the step
3690        # would be just a copy and avoid the copy.
3691        _process_device_jar =
3692            defined(invoker.bytecode_rewriter_target) || _jacoco_instrument ||
3693            defined(invoker.jar_excluded_patterns) ||
3694            defined(invoker.jar_included_patterns)
3695        if (!_process_device_jar && _is_prebuilt) {
3696          _device_processed_jar_path = invoker.jar_path
3697        } else {
3698          _device_processed_jar_path =
3699              "$target_out_dir/$_output_name.processed.jar"
3700        }
3701      }
3702
3703      # For static libraries, the javac jar output is created at the intermediate
3704      # path so that it can be processed by another target and moved to the final
3705      # spot that the .build_config.json knows about. Technically this should be done
3706      # for the ijar as well, but this is only used for APK targets where
3707      # the ijar path isn't actually used.
3708      if (_has_sources) {
3709        _final_ijar_path = "$target_out_dir/$_output_name.turbine.jar"
3710      } else {
3711        _final_ijar_path = "$target_out_dir/$_output_name.ijar.jar"
3712      }
3713
3714      if (_has_sources) {
3715        if (_build_device_jar && !_process_device_jar) {
3716          _javac_jar_path = _device_processed_jar_path
3717        } else {
3718          _javac_jar_path = "$target_out_dir/$_main_target_name.javac.jar"
3719        }
3720        _generated_jar_path =
3721            "$target_gen_dir/$_main_target_name.generated.srcjar"
3722      }
3723
3724      if (_is_prebuilt) {
3725        _unprocessed_jar_path = invoker.jar_path
3726      } else {
3727        _unprocessed_jar_path = _javac_jar_path
3728      }
3729    }
3730
3731    _java_assetres_deps = filter_include(_invoker_deps, java_resource_patterns)
3732
3733    # Cannot use minus operator because it does not work when the operand has
3734    # repeated entries.
3735    _invoker_deps_minus_assetres =
3736        filter_exclude(_invoker_deps, _java_assetres_deps)
3737    _lib_deps =
3738        filter_include(_invoker_deps_minus_assetres, java_library_patterns)
3739    _non_java_deps = filter_exclude(_invoker_deps_minus_assetres, _lib_deps)
3740
3741    _java_header_deps = []  # Turbine / ijar
3742
3743    # It would be more ideal to split this into __host and __javac, but we
3744    # combine the two concepts to save on a group() target.
3745    _java_host_deps = []  # Processed host .jar + javac .jar.
3746    _java_validate_deps = []  # Bytecode checker & errorprone.
3747
3748    foreach(_lib_dep, _lib_deps) {
3749      # Expand //foo/java -> //foo/java:java
3750      _lib_dep = get_label_info(_lib_dep, "label_no_toolchain")
3751      _java_assetres_deps += [ "${_lib_dep}__assetres" ]
3752      _java_header_deps += [ "${_lib_dep}__header" ]
3753      _java_host_deps += [ "${_lib_dep}__host" ]
3754      _java_validate_deps += [ "${_lib_dep}__validate" ]
3755    }
3756
3757    # APK and base module targets are special because:
3758    # 1) They do not follow java target naming scheme (since they are not
3759    #    generally deps, there is no need for them to).
3760    # 2) They do not bother to define a __host target.
3761    # Since __host is used as an indirect dep for the compile_java artifacts,
3762    # add the __compile_java target directly for them.
3763    if (defined(invoker.apk_under_test)) {
3764      _java_assetres_deps += [ "${invoker.apk_under_test}__java__assetres" ]
3765      _java_header_deps += [ "${invoker.apk_under_test}__java__header" ]
3766      _java_validate_deps += [ "${invoker.apk_under_test}__java__validate" ]
3767      _java_host_deps += [ "${invoker.apk_under_test}__compile_java" ]
3768    }
3769    if (defined(invoker.base_module_target)) {
3770      _java_assetres_deps += [ "${invoker.base_module_target}__java__assetres" ]
3771      _java_header_deps += [ "${invoker.base_module_target}__java__header" ]
3772      _java_validate_deps += [ "${invoker.base_module_target}__java__validate" ]
3773      _java_host_deps += [ "${invoker.base_module_target}__compile_java" ]
3774    }
3775
3776    not_needed([ "_non_java_deps" ])
3777
3778    if (_is_prebuilt || _has_sources) {
3779      # Classpath deps are used for header and dex targets, they do not need
3780      # __assetres deps.
3781      # _non_java_deps are needed for input_jars_paths that are generated.
3782      _header_classpath_deps =
3783          _java_header_deps + _non_java_deps + [ ":$_build_config_target_name" ]
3784
3785      _javac_classpath_deps =
3786          _java_host_deps + _non_java_deps + [ ":$_build_config_target_name" ]
3787
3788      _include_android_sdk = _build_device_jar
3789      if (defined(invoker.include_android_sdk)) {
3790        _include_android_sdk = invoker.include_android_sdk
3791      }
3792      if (_include_android_sdk) {
3793        if (defined(invoker.alternative_android_sdk_dep)) {
3794          _android_sdk_dep = invoker.alternative_android_sdk_dep
3795        } else {
3796          _android_sdk_dep = default_android_sdk_dep
3797        }
3798
3799        _header_classpath_deps += [ "${_android_sdk_dep}__header" ]
3800        _javac_classpath_deps += [ "${_android_sdk_dep}" ]
3801      }
3802    }
3803
3804    # Often needed, but too hard to figure out when ahead of time.
3805    not_needed([
3806                 "_header_classpath_deps",
3807                 "_javac_classpath_deps",
3808               ])
3809
3810    if (_source_files != []) {
3811      _target_sources_file = "$target_gen_dir/$_main_target_name.sources"
3812      write_file(_target_sources_file,
3813                 rebase_path(_source_files, root_build_dir))
3814    }
3815
3816    write_build_config(_build_config_target_name) {
3817      forward_variables_from(invoker,
3818                             [
3819                               "aar_path",
3820                               "annotation_processor_deps",
3821                               "base_allowlist_rtxt_path",
3822                               "direct_deps_only",
3823                               "gradle_treat_as_prebuilt",
3824                               "input_jars_paths",
3825                               "preferred_dep",
3826                               "low_classpath_priority",
3827                               "main_class",
3828                               "mergeable_android_manifests",
3829                               "module_name",
3830                               "parent_module_target",
3831                               "proguard_configs",
3832                               "proguard_enabled",
3833                               "proguard_mapping_path",
3834                               "public_target_label",
3835                               "r_text_path",
3836                               "suffix_apk_assets_used_by",
3837                               "type",
3838                               "use_interface_jars",
3839                               "version_code",
3840                               "version_name",
3841                             ])
3842      if (_type == "android_apk" || _type == "android_app_bundle_module") {
3843        forward_variables_from(
3844            invoker,
3845            [
3846              "android_manifest",
3847              "android_manifest_dep",
3848              "merged_android_manifest",
3849              "final_dex_path",
3850              "loadable_modules",
3851              "native_lib_placeholders",
3852              "res_size_info_path",
3853              "secondary_abi_loadable_modules",
3854              "secondary_abi_shared_libraries_runtime_deps_file",
3855              "secondary_native_lib_placeholders",
3856              "shared_libraries_runtime_deps_file",
3857              "library_always_compress",
3858            ])
3859      }
3860      if (_type == "android_apk") {
3861        forward_variables_from(invoker,
3862                               [
3863                                 "apk_path",
3864                                 "apk_under_test",
3865                                 "incremental_apk_path",
3866                                 "incremental_install_json_path",
3867                               ])
3868      }
3869      if (_type == "android_app_bundle_module") {
3870        forward_variables_from(invoker,
3871                               [
3872                                 "add_view_trace_events",
3873                                 "base_module_target",
3874                                 "module_pathmap_path",
3875                                 "proto_resources_path",
3876                               ])
3877      }
3878      chromium_code = _chromium_code
3879      build_config = _build_config
3880      is_prebuilt = _is_prebuilt
3881
3882      # Specifically avoid passing in invoker.base_module_target as one of the
3883      # possible_config_deps.
3884      possible_config_deps = _default_deps
3885      if (defined(invoker.deps)) {
3886        possible_config_deps += invoker.deps
3887      }
3888      if (defined(invoker.public_deps)) {
3889        possible_config_public_deps = invoker.public_deps
3890      }
3891      if (defined(invoker.asset_deps)) {
3892        possible_config_deps += invoker.asset_deps
3893      }
3894      if (defined(apk_under_test)) {
3895        possible_config_deps += [ apk_under_test ]
3896      }
3897      if (defined(_jacoco_instrument) && _jacoco_instrument) {
3898        possible_config_deps += [ _jacoco_dep ]
3899      }
3900      if (defined(_android_sdk_dep)) {
3901        possible_config_deps += [ _android_sdk_dep ]
3902      }
3903
3904      supports_android = _supports_android
3905      requires_android = _requires_android
3906      is_robolectric = _is_robolectric
3907      bypass_platform_checks = _bypass_platform_checks
3908
3909      if (defined(invoker.resources_package)) {
3910        custom_package = invoker.resources_package
3911      }
3912      if (_is_prebuilt || _has_sources) {
3913        if (_skip_header_jar) {
3914          # We are tricking everything that is looking for an ijar into looking
3915          # at the processed jar path, which is has the excluded classes
3916          # removed.
3917          ijar_path = _device_processed_jar_path
3918        } else {
3919          ijar_path = _final_ijar_path
3920        }
3921        unprocessed_jar_path = _unprocessed_jar_path
3922      }
3923      if (_build_host_jar) {
3924        host_jar_path = _host_processed_jar_path
3925      }
3926      if (_build_device_jar) {
3927        device_jar_path = _device_processed_jar_path
3928        dex_path = _dex_path
3929      }
3930      if (_source_files != []) {
3931        target_sources_file = _target_sources_file
3932      }
3933
3934      bundled_srcjars = []
3935      foreach(d, _srcjar_deps) {
3936        _dep_gen_dir = get_label_info(d, "target_gen_dir")
3937        _dep_name = get_label_info(d, "name")
3938        bundled_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ]
3939      }
3940      bundled_srcjars += _srcjars
3941      if (defined(invoker.include_java_resources) &&
3942          invoker.include_java_resources) {
3943        java_resources_jar = _unprocessed_jar_path
3944        if (defined(invoker.jar_path)) {
3945          # Use original jar_path because _jar_path points to a library without
3946          # resources.
3947        } else {
3948          java_resources_jar = _device_processed_jar_path
3949        }
3950      }
3951    }
3952
3953    if (_is_prebuilt || _has_sources) {
3954      _header_target_name = "${target_name}__header"
3955    }
3956
3957    if (_has_sources) {
3958      _kt_files = filter_include(_source_files, [ "*.kt" ])
3959      _java_files = filter_exclude(_source_files, [ "*.kt" ])
3960
3961      if (defined(invoker.enable_errorprone)) {
3962        _enable_errorprone = invoker.enable_errorprone
3963      } else {
3964        _enable_errorprone =
3965            _java_files != [] && _chromium_code && use_errorprone_java_compiler
3966      }
3967      if (_enable_errorprone) {
3968        # Rely on the header jar to provide all .class files so that it is
3969        # safe to omit generated files entirely for errorprone.
3970        _errorprone_source_files =
3971            filter_exclude(_java_files, [ "$root_gen_dir*" ])
3972        _enable_errorprone =
3973            _enable_errorprone && _errorprone_source_files != []
3974      } else {
3975        not_needed(invoker, [ "errorprone_args" ])
3976      }
3977
3978      if (defined(invoker.resources_package) && _type == "java_library") {
3979        # TODO(crbug.com/40821816): remove _bypass_platform_checks from the list
3980        # once all robolectric targets have migrated to robolectric_library.
3981        assert(_requires_android || _bypass_platform_checks || _is_robolectric,
3982               "Setting resources_package applicable only for " +
3983                   "android_library(), or robolectric_library(). " +
3984                   "Target=$target_name")
3985
3986        # Serves double purpose: Generating R.java, as well as being the
3987        #__assetres target (instead of using a separate group).
3988        _fake_rjava_target = "${target_name}__assetres"
3989        generate_r_java(_fake_rjava_target) {
3990          deps = [ ":$_build_config_target_name" ] + _java_assetres_deps +
3991                 _non_java_deps
3992          build_config = _build_config
3993
3994          # Filepath has to be exactly this because compile_java looks for the
3995          # srcjar of srcjar_deps at this location $gen_dir/$target_name.srcjar
3996          srcjar_path = "$target_gen_dir/$target_name.srcjar"
3997          package = invoker.resources_package
3998        }
3999        _srcjar_deps += [ ":$_fake_rjava_target" ]
4000      }
4001
4002      if (_kt_files != []) {
4003        _abs_kt_files = get_path_info(_kt_files, "abspath")
4004        _kt_allowlist = [
4005          "*/AsyncTabParamsManagerImpl.kt",
4006          "//third_party/androidx/*",
4007          "*/webengine_shell_apk/*",
4008          "local_modifications/pdf/java/androidx/pdf/viewer/fragment/PdfViewerFragment.kt",
4009        ]
4010        _found_kt = filter_exclude(_abs_kt_files, _kt_allowlist)
4011        assert(
4012            _found_kt == [],
4013            "Only a files in the allowlist can be included for now. Feel free to remove this assert when experimenting locally. Found: $_found_kt")
4014        _compile_kt_target_name = "${_main_target_name}__compile_kt"
4015        _kotlinc_jar_path = "$target_out_dir/$_output_name.kotlinc.jar"
4016        _kotlin_interface_jar_path =
4017            "$target_out_dir/$_output_name.kt-jvm-abi.jar"
4018        assert(filter_include(_lib_deps, [ _kotlin_stdlib_dep ]) != [],
4019               "${_main_target_name} is missing dep: $_kotlin_stdlib_dep")
4020        compile_kt(_compile_kt_target_name) {
4021          deps = _header_classpath_deps
4022          output_jar_path = _kotlinc_jar_path
4023          output_interface_jar_path = _kotlin_interface_jar_path
4024          main_target_name = _main_target_name
4025          build_config = _build_config
4026          srcjar_deps = _srcjar_deps
4027          source_files = _source_files
4028          target_sources_file = _target_sources_file
4029          chromium_code = _chromium_code
4030          include_android_sdk = _is_robolectric || _requires_android
4031        }
4032      }
4033
4034      template("compile_java_helper") {
4035        _enable_errorprone =
4036            defined(invoker.enable_errorprone) && invoker.enable_errorprone
4037        compile_java(target_name) {
4038          forward_variables_from(invoker,
4039                                 "*",
4040                                 TESTONLY_AND_VISIBILITY + [ "deps" ])
4041          deps = _header_classpath_deps
4042          if (defined(invoker.deps)) {
4043            deps += invoker.deps
4044          }
4045          if (defined(invoker.kotlin_jar_path)) {
4046            deps += [ ":$_compile_kt_target_name" ]
4047            kotlin_jar_path = invoker.kotlin_jar_path
4048          }
4049          enable_errorprone = _enable_errorprone
4050          use_turbine = defined(invoker.use_turbine) && invoker.use_turbine
4051
4052          build_config = _build_config
4053
4054          if (_enable_errorprone) {
4055            source_files = _errorprone_source_files
4056          } else {
4057            main_target_name = _main_target_name
4058            source_files = _source_files
4059            srcjar_deps = _srcjar_deps
4060            srcjars = _srcjars
4061          }
4062
4063          if (source_files != []) {
4064            target_sources_file = _target_sources_file
4065          }
4066          chromium_code = _chromium_code
4067          include_android_sdk = _is_robolectric || _requires_android
4068        }
4069      }
4070      _compile_java_forward_variables = [
4071        "additional_jar_files",
4072        "apk_name",
4073        "jar_excluded_patterns",
4074        "jar_included_patterns",
4075        "javac_args",
4076        "processor_args_javac",
4077      ]
4078
4079      if (!_skip_header_jar) {
4080        _annotation_processor_deps = []
4081        if (defined(invoker.annotation_processor_deps)) {
4082          _annotation_processor_deps = invoker.annotation_processor_deps
4083        }
4084
4085        compile_java_helper(_header_target_name) {
4086          forward_variables_from(invoker, _compile_java_forward_variables)
4087          use_turbine = true
4088          output_jar_path = _final_ijar_path
4089          generated_jar_path = _generated_jar_path
4090          deps = _annotation_processor_deps
4091          if (_kt_files != []) {
4092            kotlin_jar_path = _kotlin_interface_jar_path
4093          }
4094        }
4095      }
4096
4097      _compile_java_target = "${_main_target_name}__compile_java"
4098      compile_java_helper(_compile_java_target) {
4099        forward_variables_from(invoker, _compile_java_forward_variables)
4100        output_jar_path = _javac_jar_path
4101        if (!_skip_header_jar) {
4102          deps = [ ":$_header_target_name" ]
4103          header_jar_path = _final_ijar_path
4104          generated_jar_path = _generated_jar_path
4105        }
4106        if (_kt_files != []) {
4107          kotlin_jar_path = _kotlinc_jar_path
4108        }
4109      }
4110
4111      if (_enable_errorprone) {
4112        _compile_java_errorprone_target = "${_main_target_name}__errorprone"
4113        compile_java_helper(_compile_java_errorprone_target) {
4114          forward_variables_from(invoker, _compile_java_forward_variables)
4115          forward_variables_from(invoker, [ "skip_build_server" ])
4116          enable_errorprone = true
4117          if (defined(invoker.errorprone_args)) {
4118            if (!defined(javac_args)) {
4119              javac_args = []
4120            }
4121            javac_args += invoker.errorprone_args
4122          }
4123          if (_kt_files != []) {
4124            kotlin_jar_path = _kotlinc_jar_path
4125          }
4126          if (!_skip_header_jar) {
4127            deps = [ ":$_header_target_name" ]
4128            header_jar_path = _final_ijar_path
4129          }
4130        }
4131        _java_validate_deps += [ ":$_compile_java_errorprone_target" ]
4132      }
4133    }  # _has_sources
4134
4135    if (_is_prebuilt || _build_device_jar || _build_host_jar) {
4136      if (_has_sources) {
4137        _unprocessed_jar_deps = [ ":$_compile_java_target" ]
4138      } else {
4139        # jars might be generated by a dep.
4140        _unprocessed_jar_deps = _non_java_deps
4141      }
4142    }
4143
4144    if (defined(invoker.bytecode_rewriter_target)) {
4145      assert(_build_host_jar || _build_device_jar,
4146             "A host or device jar must be created to use bytecode rewriting")
4147
4148      _rewritten_jar = "$target_out_dir/${target_name}_rewritten.jar"
4149      _rewritten_jar_target_name = "${target_name}__rewritten"
4150      _rewriter_path = root_build_dir + "/bin/helper/" +
4151                       get_label_info(invoker.bytecode_rewriter_target, "name")
4152      _rebased_build_config = rebase_path(_build_config, root_build_dir)
4153      action_with_pydeps(_rewritten_jar_target_name) {
4154        script = "//build/android/gyp/bytecode_rewriter.py"
4155        inputs = java_paths_for_inputs + [
4156                   _rewriter_path,
4157                   _build_config,
4158                   _unprocessed_jar_path,
4159                 ]
4160        outputs = [ _rewritten_jar ]
4161        depfile = "$target_gen_dir/$target_name.d"
4162        args = [
4163          "--depfile",
4164          rebase_path(depfile, root_build_dir),
4165          "--script",
4166          rebase_path(_rewriter_path, root_build_dir),
4167          "--classpath",
4168          "@FileArg($_rebased_build_config:deps_info:javac_full_classpath)",
4169          "--classpath",
4170          "@FileArg($_rebased_build_config:android:sdk_jars)",
4171          "--input-jar",
4172          rebase_path(_unprocessed_jar_path, root_build_dir),
4173          "--output-jar",
4174          rebase_path(_rewritten_jar, root_build_dir),
4175        ]
4176        deps = _unprocessed_jar_deps + _javac_classpath_deps +
4177               [ invoker.bytecode_rewriter_target ]
4178      }
4179
4180      _unprocessed_jar_deps = []
4181      _unprocessed_jar_deps = [ ":$_rewritten_jar_target_name" ]
4182      _unprocessed_jar_path = _rewritten_jar
4183    }
4184
4185    if (_is_prebuilt) {
4186      generate_interface_jar(_header_target_name) {
4187        # Always used the unfiltered .jar to create the interface jar so that
4188        # other targets will resolve filtered classes when depending on
4189        # BuildConfig, NativeLibraries, etc.
4190        input_jar = _unprocessed_jar_path
4191        output_jar = _final_ijar_path
4192
4193        # ijar needs only _unprocessed_jar_deps, but this also needs to export
4194        # __header target from deps.
4195        deps = _unprocessed_jar_deps + _java_header_deps
4196      }
4197    }
4198
4199    if (_build_host_jar || _build_device_jar) {
4200      _enable_bytecode_checks =
4201          (!defined(invoker.enable_bytecode_checks) ||
4202           invoker.enable_bytecode_checks) && !_is_prebuilt &&
4203          android_static_analysis != "off"
4204      if (_enable_bytecode_checks) {
4205        _validate_target_name = "${target_name}__validate"
4206        check_for_missing_direct_deps(_validate_target_name) {
4207          forward_variables_from(invoker, [ "missing_classes_allowlist" ])
4208          deps = _unprocessed_jar_deps + _javac_classpath_deps +
4209                 [ ":$_build_config_target_name" ]
4210          data_deps = _java_validate_deps
4211          if (defined(_compile_java_errorprone_target)) {
4212            data_deps += [ ":$_compile_java_errorprone_target" ]
4213          }
4214
4215          include_android_sdk = _requires_android || _is_robolectric
4216          target_label =
4217              get_label_info(":${invoker.target_name}", "label_no_toolchain")
4218          input_jar = _unprocessed_jar_path
4219          build_config = _build_config
4220        }
4221      } else {
4222        not_needed(invoker, [ "missing_classes_allowlist" ])
4223      }
4224
4225      if (_build_host_jar) {
4226        _process_host_jar_target_name = "${target_name}__host"
4227        process_java_library(_process_host_jar_target_name) {
4228          forward_variables_from(invoker,
4229                                 [
4230                                   "jar_excluded_patterns",
4231                                   "jar_included_patterns",
4232                                 ])
4233
4234          # Robolectric tests require these to be on swarming.
4235          data = [ _host_processed_jar_path ]
4236          input_jar_path = _unprocessed_jar_path
4237          deps = _unprocessed_jar_deps + _javac_classpath_deps
4238          output_jar_path = _host_processed_jar_path
4239          jacoco_instrument = _jacoco_instrument
4240          if (_jacoco_instrument) {
4241            source_files = _source_files
4242            target_sources_file = _target_sources_file
4243          }
4244
4245          # _java_host_deps isn't necessary for process_java_library(), but is
4246          # necessary so that this target can be used to depend on transitive
4247          # __device targets without the need to create a separate group()
4248          # target. This trade-off works because process_java_library is fast.
4249          deps += _java_host_deps
4250
4251          # Add runtime_deps here since robolectric_binary does not depend on top-level group.
4252          if (defined(invoker.data)) {
4253            data += invoker.data
4254          }
4255          if (defined(invoker.data_deps)) {
4256            data_deps = invoker.data_deps
4257          }
4258        }
4259      }
4260
4261      if (_build_device_jar) {
4262        if (_process_device_jar) {
4263          _process_device_jar_target_name = "${target_name}__process_device"
4264          process_java_library(_process_device_jar_target_name) {
4265            forward_variables_from(invoker,
4266                                   [
4267                                     "jar_excluded_patterns",
4268                                     "jar_included_patterns",
4269                                   ])
4270            input_jar_path = _unprocessed_jar_path
4271
4272            deps = _unprocessed_jar_deps + _javac_classpath_deps
4273            output_jar_path = _device_processed_jar_path
4274            jacoco_instrument = _jacoco_instrument
4275            if (_jacoco_instrument) {
4276              source_files = _source_files
4277              target_sources_file = _target_sources_file
4278            }
4279          }
4280          _process_device_jar_deps = [ ":${_process_device_jar_target_name}" ]
4281        } else {
4282          assert(_unprocessed_jar_path == _device_processed_jar_path)
4283          _process_device_jar_deps = _unprocessed_jar_deps
4284        }
4285
4286        if (_skip_header_jar) {
4287          group(_header_target_name) {
4288            public_deps = [ ":$_process_device_jar_target_name" ]
4289          }
4290        }
4291
4292        _dex_target_name = "${target_name}__dex"
4293        dex(_dex_target_name) {
4294          forward_variables_from(invoker,
4295                                 [
4296                                   "proguard_enable_obfuscation",
4297                                   "repackage_classes",
4298                                 ])
4299          input_class_jars = [ _device_processed_jar_path ]
4300          enable_desugar = _enable_desugar
4301          ignore_desugar_missing_deps = !_enable_bytecode_checks
4302
4303          # There's no value in per-class dexing prebuilts since they never
4304          # change just one class at a time.
4305          disable_incremental = _is_prebuilt
4306          output = _dex_path
4307          deps = _process_device_jar_deps
4308
4309          if (enable_desugar) {
4310            # Desugaring with D8 requires full classpath.
4311            build_config = _build_config
4312            unprocessed_jar_path = _unprocessed_jar_path
4313            deps += _header_classpath_deps + _unprocessed_jar_deps
4314          }
4315
4316          is_library = true
4317
4318          # proguard_configs listed on java_library targets need to be marked
4319          # as inputs to at least one target so that "gn analyze" will know
4320          # about them. Although this target doesn't use them, it's a convenient spot
4321          # to list them.
4322          # https://crbug.com/827197
4323          if (compute_inputs_for_analyze && defined(invoker.proguard_configs)) {
4324            inputs = invoker.proguard_configs
4325
4326            # For the aapt-generated proguard rules.
4327            deps += _non_java_deps + _srcjar_deps
4328          }
4329        }
4330      }
4331    }
4332
4333    if (_is_java_binary) {
4334      # Targets might use the generated script while building, so make it a dep
4335      # rather than a data_dep.
4336      _java_binary_script_target_name = "${target_name}__java_binary_script"
4337      java_binary_script(_java_binary_script_target_name) {
4338        forward_variables_from(invoker,
4339                               [
4340                                 "tiered_stop_at_level_one",
4341                                 "main_class",
4342                                 "max_heap_size",
4343                                 "wrapper_script_args",
4344                               ])
4345        build_config = _build_config
4346        script_name = _main_target_name
4347        if (defined(invoker.wrapper_script_name)) {
4348          script_name = invoker.wrapper_script_name
4349        }
4350        deps = [ ":$_build_config_target_name" ]
4351        if (_is_robolectric) {
4352          # For robolectric tests, we add the sdk stub jars so that classes
4353          # that reference Android types can be loaded without throwing
4354          # NoClassDefFoundErrors. The Robolectric sandbox makes these types
4355          # available in non-stub form, but not until test classes are loaded
4356          # into it. Before being loaded into the sandbox, they must be loaded
4357          # outside of it in order to read their annotations (which configure
4358          # the sandbox), and to enumerate test methods.
4359          extra_classpath_jars = [
4360            android_sdk_jar,
4361            "$android_sdk/optional/android.test.base.jar",
4362            "$android_sdk/optional/android.test.runner.jar",
4363          ]
4364        }
4365      }
4366    }
4367
4368    if (!defined(_validate_target_name)) {
4369      _validate_target_name = "${target_name}__validate"
4370
4371      # Allow other targets to depend on this __validate one.
4372      group(_validate_target_name) {
4373        deps = _java_validate_deps
4374      }
4375    }
4376
4377    if (_supports_host && !defined(_process_host_jar_target_name)) {
4378      group("${target_name}__host") {
4379        deps = _java_host_deps
4380      }
4381    }
4382
4383    # robolectric_library can depend on java_library, so java_library must
4384    # define __assetres.
4385    if ((_is_library || _supports_android || _is_robolectric) &&
4386        !defined(_fake_rjava_target)) {
4387      group("${target_name}__assetres") {
4388        if (_supports_android || _is_robolectric) {
4389          deps = _java_assetres_deps
4390        }
4391      }
4392    }
4393
4394    # The top-level group is used:
4395    # 1) To allow building the target explicitly via ninja,
4396    # 2) To trigger all analysis deps,
4397    # 3) By custom action() targets that want to use artifacts as inputs.
4398    group(target_name) {
4399      forward_variables_from(invoker,
4400                             [
4401                               "assert_no_deps",
4402                               "data",
4403                               "data_deps",
4404                               "visibility",
4405                             ])
4406      if (_requires_android || (_supports_android && _is_library)) {
4407        # For non-robolectric targets, depend on other java target's top-level
4408        # groups so that the __dex step gets depended on.
4409        deps = _default_deps
4410        if (defined(invoker.deps)) {
4411          deps += invoker.deps
4412        }
4413        public_deps = []
4414        if (defined(invoker.public_deps)) {
4415          public_deps += invoker.public_deps
4416        }
4417        if (is_cronet_build) {
4418          _abs_deps = []
4419          foreach(dep, deps) {
4420            _abs_deps += [ get_label_info(dep, "label_no_toolchain") ]
4421          }
4422          foreach(dep, public_deps) {
4423            _abs_deps += [ get_label_info(dep, "label_no_toolchain") ]
4424          }
4425          if (defined(invoker.srcjar_deps)) {
4426            foreach(dep, invoker.srcjar_deps) {
4427              _abs_deps += [ get_label_info(dep, "label_no_toolchain") ]
4428            }
4429          }
4430          _abs_path_source_files = []
4431          if (defined(invoker.sources)) {
4432            foreach(source_file, invoker.sources) {
4433              _abs_path_source_files +=
4434                  [ get_path_info(source_file, "abspath") ]
4435            }
4436          }
4437          _abs_jar_path = ""
4438          if (defined(invoker.jar_path)) {
4439            _abs_jar_path = get_path_info(invoker.jar_path, "abspath")
4440          }
4441          _sdk_version = "current"
4442          if (defined(invoker.alternative_android_sdk_dep)) {
4443            _sdk_version = "system_current"
4444          }
4445
4446          # See crbug/1449896 for more details about the metadata fields
4447          # and why they are added.
4448          metadata = {
4449            jar_path = [ _abs_jar_path ]
4450            source_files = _abs_path_source_files
4451            all_deps = _abs_deps
4452            target_type = [ _type ]
4453            sdk_version = [ _sdk_version ]
4454          }
4455        }
4456      } else {
4457        # For robolectric targets, depend only on non-java deps and the specific
4458        # subtargets below, which will not include __dex.
4459        deps = _non_java_deps
4460        public_deps = []
4461        if (defined(invoker.public_deps)) {
4462          public_deps +=
4463              filter_exclude(invoker.public_deps, java_target_patterns)
4464        }
4465      }
4466      if (defined(_jacoco_instrument) && _jacoco_instrument) {
4467        deps += [ _jacoco_dep ]
4468      }
4469      if (defined(invoker.apk_under_test)) {
4470        deps += [ invoker.apk_under_test ]
4471      }
4472      if (defined(_process_device_jar_target_name)) {
4473        public_deps += [ ":$_process_device_jar_target_name" ]
4474      }
4475      if (defined(_dex_target_name)) {
4476        public_deps += [ ":$_dex_target_name" ]
4477      }
4478      if (_supports_android && _is_library) {
4479        # Robolectric targets define __assetres, but there's no need to build it
4480        # by default.
4481        public_deps += [ ":${target_name}__assetres" ]
4482      }
4483      if (_supports_host) {
4484        # android_* targets define __host, but there's no need to build it by
4485        # default.
4486        public_deps += [ ":${target_name}__host" ]
4487      }
4488      if (_is_java_binary) {
4489        public_deps += [ ":$_java_binary_script_target_name" ]
4490      }
4491      if (!defined(data_deps)) {
4492        data_deps = []
4493      }
4494      if (defined(_validate_target_name)) {
4495        data_deps += [ ":$_validate_target_name" ]
4496      } else {
4497        data_deps += _java_validate_deps
4498      }
4499    }
4500  }
4501}
4502
4503# Create a zip archive corresponding to an application bundle module.
4504#
4505# Compile all the components of a given android_apk_or_module() target into a
4506# zip archive suitable to later create an android_app_bundle() target. This
4507# archive's format is very similar to that on an APK, except for a few
4508# differences in internal directory layouts, and the fact that resources, as
4509# well as xml files, are compiled using a protocol-buffer based format (instead
4510# of the regular binary xml + resources.arsc).
4511#
4512# A final application bundle is built from one or more module bundle modules,
4513# plus some configuration file.
4514#
4515# Variables:
4516#   module_zip_path: Output module path.
4517#   build_config: Path to build_config of the android_apk_or_module() target.
4518#   dex_path: If module is proguarded separately from the base module, dex_path
4519#     is the path to its dex file and is passed directly to the creation script.
4520#     Otherwise, dex_path is undefined and we retrieve the module's dex file
4521#     using its build_config.
4522#   expected_libs_and_assets: Verify the list of included native libraries
4523#     and assets is consistent with the given expectation file.
4524#   expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff
4525#     with this file as the base.
4526#   is_multi_abi: If true will add a library placeholder for the missing ABI if
4527#     either the primary or the secondary ABI has no native libraries set.
4528#   module_name: The module's name.
4529#   native_libraries_config: Path to file listing native libraries to be
4530#     packaged into each module.
4531#   proguard_enabled: Optional. True if proguarding is enabled for this
4532#     bundle. Default is to enable this only for release builds. Note that
4533#     this will always perform synchronized proguarding.
4534template("create_android_app_bundle_module") {
4535  _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
4536  _rebased_app_bundle_build_config =
4537      rebase_path(invoker.app_bundle_build_config, root_build_dir)
4538
4539  forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4540  _deps = invoker.deps
4541  _script = "//build/android/gyp/apkbuilder.py"
4542
4543  # NOTE: Compared to the inputs of the "package_apk" template action,
4544  #       this list is much smaller, since finalize_apk is never called
4545  #       by apkbuild.py --format=bundle-module. This means not using
4546  #       apksigner and zipalign as well, nor the keystore. Other
4547  #       dependencies like extra native libraries are all pulled from the
4548  #       .build_config.json through @FileArg() references (see below) and
4549  #       will be listed in the generated depfile instead.
4550  _inputs = [
4551    invoker.build_config,
4552    invoker.app_bundle_build_config,
4553  ]
4554  _outputs = [ invoker.module_zip_path ]
4555  _args = [
4556    "--format=bundle-module",
4557    "--output-apk",
4558    rebase_path(invoker.module_zip_path, root_build_dir),
4559    "--resource-apk=@FileArg(" +
4560        "$_rebased_build_config:deps_info:proto_resources_path)",
4561    "--assets=@FileArg($_rebased_app_bundle_build_config:modules:${invoker.module_name}:assets)",
4562    "--uncompressed-assets=@FileArg(" +
4563        "$_rebased_build_config:deps_info:uncompressed_assets)",
4564    "--native-libs=@FileArg($_rebased_build_config:native:libraries)",
4565    "--native-libs=@FileArg($_rebased_build_config:native:loadable_modules)",
4566    "--native-lib-placeholders=@FileArg($_rebased_build_config" +
4567        ":native:native_library_placeholders)",
4568    "--secondary-native-lib-placeholders=@FileArg($_rebased_build_config" +
4569        ":native:secondary_native_library_placeholders)",
4570    "--android-abi=$android_app_abi",
4571    "--min-sdk-version=${invoker.min_sdk_version}",
4572    "--library-always-compress=@FileArg($_rebased_build_config:native:library_always_compress)",
4573  ]
4574  if (defined(android_app_secondary_abi)) {
4575    _args += [
4576      "--secondary-native-libs=@FileArg(" +
4577          "$_rebased_build_config:native:secondary_abi_libraries)",
4578      "--secondary-native-libs=@FileArg(" +
4579          "$_rebased_build_config:native:secondary_abi_loadable_modules)",
4580      "--secondary-android-abi=$android_app_secondary_abi",
4581    ]
4582  }
4583  if (defined(invoker.is_multi_abi) && invoker.is_multi_abi) {
4584    _args += [ "--is-multi-abi" ]
4585  }
4586  if (defined(invoker.uncompress_dex) && invoker.uncompress_dex) {
4587    _args += [ "--uncompress-dex" ]
4588  }
4589  if (defined(invoker.extra_assets)) {
4590    _args += [ "--assets=${invoker.extra_assets}" ]
4591  }
4592
4593  # Use either provided dex path or build config path based on type of module.
4594  if (defined(invoker.dex_path)) {
4595    _inputs += [ invoker.dex_path ]
4596    _rebased_dex_path = rebase_path(invoker.dex_path, root_build_dir)
4597    _args += [ "--dex-file=$_rebased_dex_path" ]
4598  } else {
4599    _args += [ "--dex-file=@FileArg($_rebased_build_config:final_dex:path)" ]
4600  }
4601
4602  if (treat_warnings_as_errors) {
4603    _args += [ "--warnings-as-errors" ]
4604  }
4605
4606  if (defined(invoker.expected_libs_and_assets)) {
4607    _expectations_target = "${invoker.top_target_name}_validate_libs_and_assets"
4608    action_with_pydeps(_expectations_target) {
4609      _actual_file = "$target_gen_dir/$target_name.libs_and_assets"
4610      _failure_file = "$expectations_failure_dir/" +
4611                      string_replace(invoker.expected_libs_and_assets, "/", "_")
4612      inputs = [
4613        invoker.expected_libs_and_assets,
4614        invoker.build_config,
4615      ]
4616      deps = [
4617        invoker.build_config_target,
4618        invoker.app_bundle_build_config_target,
4619      ]
4620      outputs = [
4621        _actual_file,
4622        _failure_file,
4623      ]
4624      script = _script
4625      args = _args + [
4626               "--expected-file",
4627               rebase_path(invoker.expected_libs_and_assets, root_build_dir),
4628               "--actual-file",
4629               rebase_path(_actual_file, root_build_dir),
4630               "--failure-file",
4631               rebase_path(_failure_file, root_build_dir),
4632               "--only-verify-expectations",
4633             ]
4634      if (defined(invoker.expected_libs_and_assets_base)) {
4635        inputs += [ invoker.expected_libs_and_assets_base ]
4636        args += [
4637          "--expected-file-base",
4638          rebase_path(invoker.expected_libs_and_assets_base, root_build_dir),
4639        ]
4640      }
4641      if (fail_on_android_expectations) {
4642        args += [ "--fail-on-expectations" ]
4643      }
4644    }
4645    _deps += [ ":$_expectations_target" ]
4646  }
4647
4648  action_with_pydeps(target_name) {
4649    deps = _deps
4650    inputs = _inputs
4651    outputs = _outputs
4652    script = _script
4653    depfile = "$target_gen_dir/$target_name.d"
4654    args = _args + [
4655             "--depfile",
4656             rebase_path(depfile, root_build_dir),
4657           ]
4658  }
4659}
4660
4661template("rename_jar_classes") {
4662  action_with_pydeps(target_name) {
4663    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
4664    forward_variables_from(invoker,
4665                           [
4666                             "deps",
4667                             "public_deps",
4668                           ])
4669    script = "//build/android/gyp/rename_java_classes.py"
4670    inputs = [
4671      _r8_path,
4672      invoker.input,
4673    ]
4674    outputs = [ invoker.output ]
4675    args = [
4676      "--r8-path",
4677      rebase_path(_r8_path, root_build_dir),
4678      "--input-jar",
4679      rebase_path(invoker.input, root_build_dir),
4680      "--output-jar",
4681      rebase_path(invoker.output, root_build_dir),
4682    ]
4683
4684    foreach(_rule, invoker.renaming_rules) {
4685      args += [
4686        "--map",
4687        _rule,
4688      ]
4689    }
4690  }
4691}
4692