|  | # Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | # Do not add any imports to non-//build directories here. | 
|  | # Some projects (e.g. V8) do not have non-build directories DEPS'ed in. | 
|  | import("//build/config/android/config.gni") | 
|  | import("//build/config/android/internal_rules.gni") | 
|  | import("//build/config/clang/clang.gni") | 
|  | import("//build/config/compiler/compiler.gni") | 
|  | import("//build/config/dcheck_always_on.gni") | 
|  | import("//build/toolchain/toolchain.gni") | 
|  |  | 
|  | assert(is_android) | 
|  |  | 
|  | declare_args() { | 
|  | enable_jni_tracing = false | 
|  | } | 
|  |  | 
|  | if (target_cpu == "arm") { | 
|  | _sanitizer_arch = "arm" | 
|  | } else if (target_cpu == "arm64") { | 
|  | _sanitizer_arch = "aarch64" | 
|  | } else if (target_cpu == "x86") { | 
|  | _sanitizer_arch = "i686" | 
|  | } | 
|  |  | 
|  | _sanitizer_runtimes = [] | 
|  | if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { | 
|  | _sanitizer_runtimes = [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.ubsan_standalone-$_sanitizer_arch-android.so" ] | 
|  | } | 
|  |  | 
|  | # Creates a dist directory for a native executable. | 
|  | # | 
|  | # Running a native executable on a device requires all the shared library | 
|  | # dependencies of that executable. To make it easier to install and run such an | 
|  | # executable, this will create a directory containing the native exe and all | 
|  | # it's library dependencies. | 
|  | # | 
|  | # Note: It's usually better to package things as an APK than as a native | 
|  | # executable. | 
|  | # | 
|  | # Variables | 
|  | #   dist_dir: Directory for the exe and libraries. Everything in this directory | 
|  | #     will be deleted before copying in the exe and libraries. | 
|  | #   binary: Path to (stripped) executable. | 
|  | #   extra_files: List of extra files to copy in (optional). | 
|  | # | 
|  | # Example | 
|  | #   create_native_executable_dist("foo_dist") { | 
|  | #     dist_dir = "$root_build_dir/foo_dist" | 
|  | #     binary = "$root_build_dir/foo" | 
|  | #     deps = [ ":the_thing_that_makes_foo" ] | 
|  | #   } | 
|  | template("create_native_executable_dist") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list" | 
|  |  | 
|  | _runtime_deps_file = "$target_gen_dir/${target_name}.runtimedeps" | 
|  | _runtime_deps_target_name = "${target_name}__runtime_deps" | 
|  | group(_runtime_deps_target_name) { | 
|  | data = _sanitizer_runtimes | 
|  | data_deps = [] | 
|  | if (defined(invoker.deps)) { | 
|  | data_deps += invoker.deps | 
|  | } | 
|  | if (is_component_build || is_asan) { | 
|  | data_deps += [ "//build/android:cpplib_stripped" ] | 
|  | } | 
|  | write_runtime_deps = _runtime_deps_file | 
|  | } | 
|  |  | 
|  | _find_deps_target_name = "${target_name}__find_library_dependencies" | 
|  |  | 
|  | # TODO(agrieve): Extract dependent libs from GN rather than readelf. | 
|  | action(_find_deps_target_name) { | 
|  | deps = invoker.deps + [ ":$_runtime_deps_target_name" ] | 
|  | script = "//build/android/gyp/write_ordered_libraries.py" | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  | inputs = [ | 
|  | invoker.binary, | 
|  | _runtime_deps_file, | 
|  | android_readelf, | 
|  | ] | 
|  | outputs = [ | 
|  | _libraries_list, | 
|  | ] | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--runtime-deps", | 
|  | rebase_path(_runtime_deps_file, root_build_dir), | 
|  | "--output", | 
|  | rebase_path(_libraries_list, root_build_dir), | 
|  | "--readelf", | 
|  | rebase_path(android_readelf, root_build_dir), | 
|  | ] | 
|  | } | 
|  |  | 
|  | copy_ex(target_name) { | 
|  | inputs = [ | 
|  | _libraries_list, | 
|  | invoker.binary, | 
|  | ] | 
|  |  | 
|  | dest = invoker.dist_dir | 
|  | data = [ | 
|  | "${invoker.dist_dir}/", | 
|  | ] | 
|  |  | 
|  | _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir) | 
|  | _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir) | 
|  | args = [ | 
|  | "--clear", | 
|  | "--files=@FileArg($_rebased_libraries_list:lib_paths)", | 
|  | "--files=$_rebased_binaries_list", | 
|  | ] | 
|  | if (defined(invoker.extra_files)) { | 
|  | _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir) | 
|  | args += [ "--files=$_rebased_extra_files" ] | 
|  | } | 
|  |  | 
|  | _depfile = "$target_gen_dir/$target_name.d" | 
|  | _stamp_file = "$target_gen_dir/$target_name.stamp" | 
|  | outputs = [ | 
|  | _stamp_file, | 
|  | ] | 
|  | args += [ | 
|  | "--depfile", | 
|  | rebase_path(_depfile, root_build_dir), | 
|  | "--stamp", | 
|  | rebase_path(_stamp_file, root_build_dir), | 
|  | ] | 
|  |  | 
|  | deps = [ | 
|  | ":$_find_deps_target_name", | 
|  | ] | 
|  | if (defined(invoker.deps)) { | 
|  | deps += invoker.deps | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Writes a script to root_out_dir/bin that passes --output-directory to the | 
|  | # wrapped script, in addition to forwarding arguments. Most / all of these | 
|  | # wrappers should be made deps of //tools/android:android_tools. | 
|  | # | 
|  | # Variables | 
|  | #   target: Script to wrap. | 
|  | #   flag_name: Default is "--output-directory" | 
|  | # | 
|  | # Example | 
|  | #   wrapper_script("foo_wrapper") { | 
|  | #     target = "//pkg/foo.py" | 
|  | #   } | 
|  | template("wrapper_script") { | 
|  | action(target_name) { | 
|  | _name = get_path_info(invoker.target, "name") | 
|  | _output = "$root_out_dir/bin/$_name" | 
|  |  | 
|  | script = "//build/android/gyp/create_tool_wrapper.py" | 
|  | outputs = [ | 
|  | _output, | 
|  | ] | 
|  |  | 
|  | # The target isn't actually used by the script, but it's nice to have GN | 
|  | # check that it exists. | 
|  | inputs = [ | 
|  | invoker.target, | 
|  | ] | 
|  | args = [ | 
|  | "--output", | 
|  | rebase_path(_output, root_build_dir), | 
|  | "--target", | 
|  | rebase_path(invoker.target, root_build_dir), | 
|  | "--output-directory", | 
|  | rebase_path(root_out_dir, root_build_dir), | 
|  | ] | 
|  | if (defined(invoker.flag_name)) { | 
|  | args += [ "--flag-name=${invoker.flag_name}" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (enable_java_templates) { | 
|  | import("//build/config/sanitizers/sanitizers.gni") | 
|  | import("//tools/grit/grit_rule.gni") | 
|  |  | 
|  | # Declare a jni target | 
|  | # | 
|  | # This target generates the native jni bindings for a set of .java files. | 
|  | # | 
|  | # See base/android/jni_generator/jni_generator.py for more info about the | 
|  | # format of generating JNI bindings. | 
|  | # | 
|  | # Variables | 
|  | #   sources: list of .java files to generate jni for | 
|  | #   jni_package: subdirectory path for generated bindings | 
|  | # | 
|  | # Example | 
|  | #   generate_jni("foo_jni") { | 
|  | #     sources = [ | 
|  | #       "android/java/src/org/chromium/foo/Foo.java", | 
|  | #       "android/java/src/org/chromium/foo/FooUtil.java", | 
|  | #     ] | 
|  | #     jni_package = "foo" | 
|  | #   } | 
|  | template("generate_jni") { | 
|  | set_sources_assignment_filter([]) | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | _base_output_dir = "${target_gen_dir}/${target_name}" | 
|  | _package_output_dir = "${_base_output_dir}/${invoker.jni_package}" | 
|  | _jni_output_dir = "${_package_output_dir}/jni" | 
|  |  | 
|  | if (defined(invoker.jni_generator_include)) { | 
|  | _jni_generator_include = invoker.jni_generator_include | 
|  | _jni_generator_include_deps = [] | 
|  | } else { | 
|  | _jni_generator_include = | 
|  | "//base/android/jni_generator/jni_generator_helper.h" | 
|  | _jni_generator_include_deps = [ | 
|  | # Using //base/android/jni_generator/jni_generator_helper.h introduces | 
|  | # a dependency on debugging_buildflags indirectly through | 
|  | # base/android/jni_android.h, which is part of the //base target. | 
|  | # This can't depend directly on //base without causing a dependency | 
|  | # cycle, though. | 
|  | "//base:debugging_buildflags", | 
|  | ] | 
|  | } | 
|  |  | 
|  | _foreach_target_name = "${target_name}__jni_gen" | 
|  | action_foreach(_foreach_target_name) { | 
|  | script = "//base/android/jni_generator/jni_generator.py" | 
|  | depfile = "$target_gen_dir/$target_name.{{source_name_part}}.d" | 
|  | sources = invoker.sources | 
|  | outputs = [ | 
|  | "${_jni_output_dir}/{{source_name_part}}_jni.h", | 
|  | ] | 
|  |  | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--input_file={{source}}", | 
|  | "--ptr_type=long", | 
|  | "--output_dir", | 
|  | rebase_path(_jni_output_dir, root_build_dir), | 
|  | "--includes", | 
|  | rebase_path(_jni_generator_include, _jni_output_dir), | 
|  | ] | 
|  |  | 
|  | if (enable_profiling) { | 
|  | args += [ "--enable_profiling" ] | 
|  | } | 
|  | if (defined(invoker.namespace)) { | 
|  | args += [ "-n ${invoker.namespace}" ] | 
|  | } | 
|  | if (enable_jni_tracing) { | 
|  | args += [ "--enable_tracing" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | config("jni_includes_${target_name}") { | 
|  | # TODO(cjhopman): #includes should probably all be relative to | 
|  | # _base_output_dir. Remove that from this config once the includes are | 
|  | # updated. | 
|  | include_dirs = [ | 
|  | _base_output_dir, | 
|  | _package_output_dir, | 
|  | ] | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "public_deps", | 
|  | "visibility", | 
|  | ]) | 
|  | if (!defined(public_deps)) { | 
|  | public_deps = [] | 
|  | } | 
|  | public_deps += [ ":$_foreach_target_name" ] | 
|  | public_deps += _jni_generator_include_deps | 
|  | public_configs = [ ":jni_includes_${target_name}" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a jni target for a prebuilt jar | 
|  | # | 
|  | # This target generates the native jni bindings for a set of classes in a .jar. | 
|  | # | 
|  | # See base/android/jni_generator/jni_generator.py for more info about the | 
|  | # format of generating JNI bindings. | 
|  | # | 
|  | # Variables | 
|  | #   classes: list of .class files in the jar to generate jni for. These should | 
|  | #     include the full path to the .class file. | 
|  | #   jni_package: subdirectory path for generated bindings | 
|  | #   jar_file: the path to the .jar. If not provided, will default to the sdk's | 
|  | #     android.jar | 
|  | # | 
|  | #   deps, public_deps: As normal | 
|  | # | 
|  | # Example | 
|  | #   generate_jar_jni("foo_jni") { | 
|  | #     classes = [ | 
|  | #       "android/view/Foo.class", | 
|  | #     ] | 
|  | #     jni_package = "foo" | 
|  | #   } | 
|  | template("generate_jar_jni") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | if (defined(invoker.jar_file)) { | 
|  | _jar_file = invoker.jar_file | 
|  | } else { | 
|  | _jar_file = android_sdk_jar | 
|  | } | 
|  |  | 
|  | _base_output_dir = "${target_gen_dir}/${target_name}/${invoker.jni_package}" | 
|  | _jni_output_dir = "${_base_output_dir}/jni" | 
|  |  | 
|  | if (defined(invoker.jni_generator_include)) { | 
|  | _jni_generator_include = invoker.jni_generator_include | 
|  | } else { | 
|  | _jni_generator_include = | 
|  | "//base/android/jni_generator/jni_generator_helper.h" | 
|  | } | 
|  |  | 
|  | # TODO(cjhopman): make jni_generator.py support generating jni for multiple | 
|  | # .class files from a .jar. | 
|  | _jni_actions = [] | 
|  | foreach(_class, invoker.classes) { | 
|  | _classname = get_path_info(_class, "name") | 
|  | _jni_target_name = "${target_name}__jni_${_classname}" | 
|  | _jni_actions += [ ":$_jni_target_name" ] | 
|  | action(_jni_target_name) { | 
|  | # The sources aren't compiled so don't check their dependencies. | 
|  | check_includes = false | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  | script = "//base/android/jni_generator/jni_generator.py" | 
|  | inputs = [ | 
|  | _jar_file, | 
|  | ] | 
|  | outputs = [ | 
|  | "${_jni_output_dir}/${_classname}_jni.h", | 
|  | ] | 
|  |  | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--jar_file", | 
|  | rebase_path(_jar_file, root_build_dir), | 
|  | "--input_file", | 
|  | _class, | 
|  | "--ptr_type=long", | 
|  | "--output_dir", | 
|  | rebase_path(_jni_output_dir, root_build_dir), | 
|  | "--includes", | 
|  | rebase_path(_jni_generator_include, _jni_output_dir), | 
|  | ] | 
|  |  | 
|  | if (enable_profiling) { | 
|  | args += [ "--enable_profiling" ] | 
|  | } | 
|  | if (enable_jni_tracing) { | 
|  | args += [ "--enable_tracing" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | config("jni_includes_${target_name}") { | 
|  | include_dirs = [ _base_output_dir ] | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | public_deps = [] | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "public_deps", | 
|  | "visibility", | 
|  | ]) | 
|  | public_deps += _jni_actions | 
|  | public_configs = [ ":jni_includes_${target_name}" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a jni registration target. | 
|  | # | 
|  | # This target generates a header file calling JNI registration functions | 
|  | # created by generate_jni and generate_jar_jni. | 
|  | # | 
|  | # See base/android/jni_generator/jni_registration_generator.py for more info | 
|  | # about the format of the header file. | 
|  | # | 
|  | # Variables | 
|  | #   target: The Apk target to generate registrations for. | 
|  | #   output: Path to the generated .h file. | 
|  | #   exception_files: List of .java files that should be ignored when searching | 
|  | #   for native methods. (optional) | 
|  | # | 
|  | # Example | 
|  | #   generate_jni_registration("chrome_jni_registration") { | 
|  | #     target = ":chrome_public_apk" | 
|  | #     output = "$root_gen_dir/chrome/browser/android/${target_name}.h" | 
|  | #     exception_files = [ | 
|  | #       "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java", | 
|  | #       "//base/android/java/src/org/chromium/base/library_loader/Linker.java", | 
|  | #       "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java", | 
|  | #     ] | 
|  | #   } | 
|  | template("generate_jni_registration") { | 
|  | action(target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  | _build_config = get_label_info(invoker.target, "target_gen_dir") + "/" + | 
|  | get_label_info(invoker.target, "name") + ".build_config" | 
|  | _rebased_build_config = rebase_path(_build_config, root_build_dir) | 
|  |  | 
|  | _rebase_exception_java_files = | 
|  | rebase_path(invoker.exception_files, root_build_dir) | 
|  |  | 
|  | script = "//base/android/jni_generator/jni_registration_generator.py" | 
|  | deps = [ | 
|  | "${invoker.target}__build_config", | 
|  | ] | 
|  | inputs = [ | 
|  | _build_config, | 
|  | ] | 
|  | outputs = [ | 
|  | invoker.output, | 
|  | ] | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  |  | 
|  | args = [ | 
|  | # This is a list of .sources files. | 
|  | "--sources_files=@FileArg($_rebased_build_config:jni:all_source)", | 
|  | "--output", | 
|  | rebase_path(invoker.output, root_build_dir), | 
|  | "--no_register_java=$_rebase_exception_java_files", | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a target for c-preprocessor-generated java files | 
|  | # | 
|  | # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum | 
|  | #       rule instead. | 
|  | # | 
|  | # This target generates java files using the host C pre-processor. Each file in | 
|  | # sources will be compiled using the C pre-processor. If include_path is | 
|  | # specified, it will be passed (with --I) to the pre-processor. | 
|  | # | 
|  | # This target will create a single .srcjar. Adding this target to an | 
|  | # android_library target's srcjar_deps will make the generated java files be | 
|  | # included in that library's final outputs. | 
|  | # | 
|  | # Variables | 
|  | #   sources: list of files to be processed by the C pre-processor. For each | 
|  | #     file in sources, there will be one .java file in the final .srcjar. For a | 
|  | #     file named FooBar.template, a java file will be created with name | 
|  | #     FooBar.java. | 
|  | #   inputs: additional compile-time dependencies. Any files | 
|  | #     `#include`-ed in the templates should be listed here. | 
|  | #   package_path: this will be the subdirectory for each .java file in the | 
|  | #     .srcjar. | 
|  | # | 
|  | # Example | 
|  | #   java_cpp_template("foo_generated_enum") { | 
|  | #     sources = [ | 
|  | #       "android/java/templates/Foo.template", | 
|  | #     ] | 
|  | #     inputs = [ | 
|  | #       "android/java/templates/native_foo_header.h", | 
|  | #     ] | 
|  | # | 
|  | #     package_path = "org/chromium/base/library_loader" | 
|  | #     include_path = "android/java/templates" | 
|  | #   } | 
|  | template("java_cpp_template") { | 
|  | set_sources_assignment_filter([]) | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | _include_path = "//" | 
|  | if (defined(invoker.include_path)) { | 
|  | _include_path = invoker.include_path | 
|  | } | 
|  |  | 
|  | _apply_gcc_target_name = "${target_name}__apply_gcc" | 
|  | _base_gen_dir = "${target_gen_dir}/${target_name}/java_cpp_template" | 
|  | _package_path = invoker.package_path | 
|  |  | 
|  | action_foreach(_apply_gcc_target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "inputs", | 
|  | "public_deps", | 
|  | "data_deps", | 
|  | ]) | 
|  | script = "//build/android/gyp/gcc_preprocess.py" | 
|  | depfile = | 
|  | "${target_gen_dir}/${invoker.target_name}_{{source_name_part}}.d" | 
|  |  | 
|  | sources = invoker.sources | 
|  |  | 
|  | outputs = [ | 
|  | "$_base_gen_dir/${_package_path}/{{source_name_part}}.java", | 
|  | ] | 
|  |  | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--include-path", | 
|  | rebase_path(_include_path, root_build_dir), | 
|  | "--output", | 
|  | rebase_path(outputs[0], root_build_dir), | 
|  | "--template={{source}}", | 
|  | ] | 
|  |  | 
|  | if (defined(invoker.defines)) { | 
|  | foreach(_def, invoker.defines) { | 
|  | args += [ | 
|  | "--defines", | 
|  | _def, | 
|  | ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Filter out .d files. | 
|  | set_sources_assignment_filter([ "*.d" ]) | 
|  | sources = get_target_outputs(":$_apply_gcc_target_name") | 
|  |  | 
|  | zip(target_name) { | 
|  | forward_variables_from(invoker, [ "visibility" ]) | 
|  | inputs = sources | 
|  | output = "${target_gen_dir}/${target_name}.srcjar" | 
|  | base_dir = _base_gen_dir | 
|  | deps = [ | 
|  | ":$_apply_gcc_target_name", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a target for generating Java classes from C++ enums. | 
|  | # | 
|  | # This target generates Java files from C++ enums using a script. | 
|  | # | 
|  | # This target will create a single .srcjar. Adding this target to an | 
|  | # android_library target's srcjar_deps will make the generated java files be | 
|  | # included in that library's final outputs. | 
|  | # | 
|  | # Variables | 
|  | #   sources: list of files to be processed by the script. For each annotated | 
|  | #     enum contained in the sources files the script will generate a .java | 
|  | #     file with the same name as the name of the enum. | 
|  | # | 
|  | # Example | 
|  | #   java_cpp_enum("foo_generated_enum") { | 
|  | #     sources = [ | 
|  | #       "src/native_foo_header.h", | 
|  | #     ] | 
|  | #   } | 
|  | template("java_cpp_enum") { | 
|  | set_sources_assignment_filter([]) | 
|  | action(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "sources", | 
|  | "testonly", | 
|  | "visibility", | 
|  | ]) | 
|  |  | 
|  | # The sources aren't compiled so don't check their dependencies. | 
|  | check_includes = false | 
|  | script = "//build/android/gyp/java_cpp_enum.py" | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  |  | 
|  | _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" | 
|  | _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir) | 
|  | _rebased_sources = rebase_path(invoker.sources, root_build_dir) | 
|  |  | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--srcjar=$_rebased_srcjar_path", | 
|  | ] + _rebased_sources | 
|  | outputs = [ | 
|  | _srcjar_path, | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a target for processing a Jinja template. | 
|  | # | 
|  | # Variables | 
|  | #   input: The template file to be processed. | 
|  | #   output: Where to save the result. | 
|  | #   variables: (Optional) A list of variables to make available to the template | 
|  | #     processing environment, e.g. ["name=foo", "color=red"]. | 
|  | # | 
|  | # Example | 
|  | #   jinja_template("chrome_public_manifest") { | 
|  | #     input = "java/AndroidManifest.xml" | 
|  | #     output = "$target_gen_dir/AndroidManifest.xml" | 
|  | #   } | 
|  | template("jinja_template") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | action(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "visibility", | 
|  | "deps", | 
|  | ]) | 
|  |  | 
|  | inputs = [ | 
|  | invoker.input, | 
|  | ] | 
|  | script = "//build/android/gyp/jinja_template.py" | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  |  | 
|  | outputs = [ | 
|  | invoker.output, | 
|  | ] | 
|  |  | 
|  | args = [ | 
|  | "--loader-base-dir", | 
|  | rebase_path("//", root_build_dir), | 
|  | "--inputs", | 
|  | rebase_path(invoker.input, root_build_dir), | 
|  | "--output", | 
|  | rebase_path(invoker.output, root_build_dir), | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | ] | 
|  | if (defined(invoker.variables)) { | 
|  | args += [ "--variables=${invoker.variables}" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a target for processing Android resources as Jinja templates. | 
|  | # | 
|  | # This takes an Android resource directory where each resource is a Jinja | 
|  | # template, processes each template, then packages the results in a zip file | 
|  | # which can be consumed by an android resources, library, or apk target. | 
|  | # | 
|  | # If this target is included in the deps of an android resources/library/apk, | 
|  | # the resources will be included with that target. | 
|  | # | 
|  | # Variables | 
|  | #   resources: The list of resources files to process. | 
|  | #   res_dir: The resource directory containing the resources. | 
|  | #   variables: (Optional) A list of variables to make available to the template | 
|  | #     processing environment, e.g. ["name=foo", "color=red"]. | 
|  | # | 
|  | # Example | 
|  | #   jinja_template_resources("chrome_public_template_resources") { | 
|  | #     res_dir = "res_template" | 
|  | #     resources = ["res_template/xml/syncable.xml"] | 
|  | #     variables = ["color=red"] | 
|  | #   } | 
|  | template("jinja_template_resources") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | # JUnit tests use resource zip files. These must not be put in gen/ | 
|  | # directory or they will not be available to tester bots. | 
|  | _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) | 
|  | _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  |  | 
|  | write_build_config("${target_name}__build_config") { | 
|  | build_config = _build_config | 
|  | resources_zip = _resources_zip | 
|  | type = "android_resources" | 
|  | if (defined(invoker.deps)) { | 
|  | possible_config_deps = invoker.deps | 
|  | } | 
|  | } | 
|  |  | 
|  | action("${target_name}__template") { | 
|  | forward_variables_from(invoker, [ "deps" ]) | 
|  | inputs = invoker.resources | 
|  | script = "//build/android/gyp/jinja_template.py" | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  |  | 
|  | outputs = [ | 
|  | _resources_zip, | 
|  | ] | 
|  |  | 
|  | _rebased_resources = rebase_path(invoker.resources, root_build_dir) | 
|  | args = [ | 
|  | "--inputs=${_rebased_resources}", | 
|  | "--inputs-base-dir", | 
|  | rebase_path(invoker.res_dir, root_build_dir), | 
|  | "--outputs-zip", | 
|  | rebase_path(_resources_zip, root_build_dir), | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | ] | 
|  | if (defined(invoker.variables)) { | 
|  | variables = invoker.variables | 
|  | args += [ "--variables=${variables}" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | public_deps = [ | 
|  | ":${target_name}__build_config", | 
|  | ":${target_name}__template", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android resources target | 
|  | # | 
|  | # This creates a resources zip file that will be used when building an Android | 
|  | # library or apk and included into a final apk. | 
|  | # | 
|  | # To include these resources in a library/apk, this target should be listed in | 
|  | # the library's deps. A library/apk will also include any resources used by its | 
|  | # own dependencies. | 
|  | # | 
|  | # Variables | 
|  | #   deps: Specifies the dependencies of this target. Any Android resources | 
|  | #     listed in deps will be included by libraries/apks that depend on this | 
|  | #     target. | 
|  | #   resource_dirs: List of directories containing resources for this target. | 
|  | #   generated_resource_dirs: List of directories containing resources for this | 
|  | #     target which are *generated* by a dependency. |generated_resource_files| | 
|  | #     must be specified if |generated_resource_dirs| is specified. | 
|  | #   generated_resource_files: List of all files in |generated_resource_dirs|. | 
|  | #     |generated_resource_dirs| must be specified in |generated_resource_files| | 
|  | #     is specified. | 
|  | #   android_manifest: AndroidManifest.xml for this target (optional). Will be | 
|  | #     merged into apks that directly or indirectly depend on this target. | 
|  | #   android_manifest_dep: Target that generates AndroidManifest (if applicable) | 
|  | #   custom_package: java package for generated .java files. | 
|  | #   v14_skip: If true, don't run v14 resource generator on this. Defaults to | 
|  | #     false. (see build/android/gyp/generate_v14_compatible_resources.py) | 
|  | #   shared_resources: If true make a resource package that can be loaded by a | 
|  | #     different application at runtime to access the package's resources. | 
|  | #   r_text_file: (optional) path to pre-generated R.txt to be used when | 
|  | #     generating R.java instead of resource-based aapt-generated one. | 
|  | #   create_srcjar: If false, does not create an R.java file. Needed only for | 
|  | #     prebuilts that have R.txt files that do not match their res/ | 
|  | #     (Play Services). | 
|  | # | 
|  | # Example: | 
|  | #   android_resources("foo_resources") { | 
|  | #     deps = [":foo_strings_grd"] | 
|  | #     resource_dirs = ["res"] | 
|  | #     custom_package = "org.chromium.foo" | 
|  | #   } | 
|  | # | 
|  | #   android_resources("foo_resources_overrides") { | 
|  | #     deps = [":foo_resources"] | 
|  | #     resource_dirs = ["res_overrides"] | 
|  | #   } | 
|  | template("android_resources") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | _base_path = "$target_gen_dir/$target_name" | 
|  |  | 
|  | # JUnit tests use resource zip files. These must not be put in gen/ | 
|  | # directory or they will not be available to tester bots. | 
|  | _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) | 
|  | _zip_path = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" | 
|  | _r_text_out_path = _base_path + "_R.txt" | 
|  | _build_config = _base_path + ".build_config" | 
|  | _build_config_target_name = "${target_name}__build_config" | 
|  |  | 
|  | if (!defined(invoker.create_srcjar) || invoker.create_srcjar) { | 
|  | _srcjar_path = _base_path + ".srcjar" | 
|  | } | 
|  |  | 
|  | write_build_config(_build_config_target_name) { | 
|  | type = "android_resources" | 
|  | build_config = _build_config | 
|  | resources_zip = _zip_path | 
|  |  | 
|  | resource_dirs = invoker.resource_dirs | 
|  | if (defined(invoker.generated_resource_dirs)) { | 
|  | resource_dirs += invoker.generated_resource_dirs | 
|  | } | 
|  |  | 
|  | if (defined(_srcjar_path)) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "android_manifest", | 
|  | "android_manifest_dep", | 
|  | "custom_package", | 
|  | ]) | 
|  |  | 
|  | # No package means resources override their deps. | 
|  | if (defined(custom_package) || defined(android_manifest)) { | 
|  | r_text = _r_text_out_path | 
|  | } else { | 
|  | assert(defined(invoker.deps), | 
|  | "Must specify deps when custom_package is omitted.") | 
|  | } | 
|  | srcjar = _srcjar_path | 
|  | } | 
|  |  | 
|  | if (defined(invoker.deps)) { | 
|  | possible_config_deps = invoker.deps | 
|  | } | 
|  | } | 
|  |  | 
|  | prepare_resources(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "android_manifest", | 
|  | "custom_package", | 
|  | "deps", | 
|  | "generated_resource_dirs", | 
|  | "generated_resource_files", | 
|  | "resource_dirs", | 
|  | "v14_skip", | 
|  | ]) | 
|  | if (!defined(deps)) { | 
|  | deps = [] | 
|  | } | 
|  | deps += [ ":$_build_config_target_name" ] | 
|  | if (defined(invoker.android_manifest_dep)) { | 
|  | deps += [ invoker.android_manifest_dep ] | 
|  | } | 
|  |  | 
|  | build_config = _build_config | 
|  | zip_path = _zip_path | 
|  | r_text_out_path = _r_text_out_path | 
|  |  | 
|  | if (defined(invoker.r_text_file)) { | 
|  | r_text_in_path = invoker.r_text_file | 
|  | } | 
|  | if (defined(_srcjar_path)) { | 
|  | srcjar_path = _srcjar_path | 
|  | } | 
|  |  | 
|  | # Always generate R.onResourcesLoaded() method, it is required for | 
|  | # compiling ResourceRewriter, there is no side effect because the | 
|  | # generated R.class isn't used in final apk. | 
|  | shared_resources = true | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android assets target. | 
|  | # | 
|  | # Defines a set of files to include as assets in a dependent apk. | 
|  | # | 
|  | # To include these assets in an apk, this target should be listed in | 
|  | # the apk's deps, or in the deps of a library target used by an apk. | 
|  | # | 
|  | # Variables | 
|  | #   deps: Specifies the dependencies of this target. Any Android assets | 
|  | #     listed in deps will be included by libraries/apks that depend on this | 
|  | #     target. | 
|  | #   sources: List of files to include as assets. | 
|  | #   renaming_sources: List of files to include as assets and be renamed. | 
|  | #   renaming_destinations: List of asset paths for files in renaming_sources. | 
|  | #   disable_compression: Whether to disable compression for files that are | 
|  | #     known to be compressable (default: false). | 
|  | #   treat_as_locale_paks: Causes base's BuildConfig.java to consider these | 
|  | #     assets to be locale paks. | 
|  | # | 
|  | # Example: | 
|  | # android_assets("content_shell_assets") { | 
|  | #   deps = [ | 
|  | #     ":generates_foo", | 
|  | #     ":other_assets", | 
|  | #     ] | 
|  | #   sources = [ | 
|  | #     "//path/asset1.png", | 
|  | #     "//path/asset2.png", | 
|  | #     "$target_gen_dir/foo.dat", | 
|  | #   ] | 
|  | # } | 
|  | # | 
|  | # android_assets("overriding_content_shell_assets") { | 
|  | #   deps = [ ":content_shell_assets" ] | 
|  | #   # Override foo.dat from content_shell_assets. | 
|  | #   sources = [ "//custom/foo.dat" ] | 
|  | #   renaming_sources = [ "//path/asset2.png" ] | 
|  | #   renaming_destinations = [ "renamed/asset2.png" ] | 
|  | # } | 
|  | template("android_assets") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  | _build_config_target_name = "${target_name}__build_config" | 
|  |  | 
|  | write_build_config(_build_config_target_name) { | 
|  | type = "android_assets" | 
|  | build_config = _build_config | 
|  |  | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "disable_compression", | 
|  | "treat_as_locale_paks", | 
|  | ]) | 
|  |  | 
|  | if (defined(invoker.deps)) { | 
|  | possible_config_deps = invoker.deps | 
|  | } | 
|  |  | 
|  | if (defined(invoker.sources)) { | 
|  | asset_sources = invoker.sources | 
|  | } | 
|  | if (defined(invoker.renaming_sources)) { | 
|  | assert(defined(invoker.renaming_destinations)) | 
|  | _source_count = 0 | 
|  | foreach(_, invoker.renaming_sources) { | 
|  | _source_count += 1 | 
|  | } | 
|  | _dest_count = 0 | 
|  | foreach(_, invoker.renaming_destinations) { | 
|  | _dest_count += 1 | 
|  | } | 
|  | assert( | 
|  | _source_count == _dest_count, | 
|  | "android_assets() renaming_sources.length != renaming_destinations.length") | 
|  | asset_renaming_sources = invoker.renaming_sources | 
|  | asset_renaming_destinations = invoker.renaming_destinations | 
|  | } | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "visibility", | 
|  | ]) | 
|  | public_deps = [ | 
|  | ":$_build_config_target_name", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a group() that supports forwarding java dependency information. | 
|  | # | 
|  | # Example | 
|  | #  java_group("conditional_deps") { | 
|  | #    if (enable_foo) { | 
|  | #      deps = [":foo_java"] | 
|  | #    } | 
|  | #  } | 
|  | template("java_group") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  | write_build_config("${target_name}__build_config") { | 
|  | type = "group" | 
|  | build_config = "$target_gen_dir/${invoker.target_name}.build_config" | 
|  | supports_android = true | 
|  | if (defined(invoker.deps)) { | 
|  | possible_config_deps = invoker.deps | 
|  | } | 
|  | } | 
|  | group(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  | if (!defined(deps)) { | 
|  | deps = [] | 
|  | } | 
|  | deps += [ ":${target_name}__build_config" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a target that generates localized strings.xml from a .grd file. | 
|  | # | 
|  | # If this target is included in the deps of an android resources/library/apk, | 
|  | # the strings.xml will be included with that target. | 
|  | # | 
|  | # Variables | 
|  | #   deps: Specifies the dependencies of this target. | 
|  | #   grd_file: Path to the .grd file to generate strings.xml from. | 
|  | #   outputs: Expected grit outputs (see grit rule). | 
|  | # | 
|  | # Example | 
|  | #  java_strings_grd("foo_strings_grd") { | 
|  | #    grd_file = "foo_strings.grd" | 
|  | #  } | 
|  | template("java_strings_grd") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | # JUnit tests use resource zip files. These must not be put in gen/ | 
|  | # directory or they will not be available to tester bots. | 
|  | _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) | 
|  | _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  |  | 
|  | write_build_config("${target_name}__build_config") { | 
|  | type = "android_resources" | 
|  | build_config = _build_config | 
|  | resources_zip = _resources_zip | 
|  | } | 
|  |  | 
|  | _grit_target_name = "${target_name}__grit" | 
|  | _grit_output_dir = "$target_gen_dir/${target_name}_grit_output" | 
|  |  | 
|  | grit(_grit_target_name) { | 
|  | forward_variables_from(invoker, [ "deps" ]) | 
|  | grit_flags = [ | 
|  | "-E", | 
|  | "ANDROID_JAVA_TAGGED_ONLY=false", | 
|  | ] | 
|  | output_dir = _grit_output_dir | 
|  | resource_ids = "" | 
|  | source = invoker.grd_file | 
|  | outputs = invoker.outputs | 
|  | } | 
|  |  | 
|  | zip(target_name) { | 
|  | base_dir = _grit_output_dir | 
|  |  | 
|  | # This needs to get outputs from grit's internal target, not the final | 
|  | # source_set. | 
|  | inputs = get_target_outputs(":${_grit_target_name}_grit") | 
|  | output = _resources_zip | 
|  | deps = [ | 
|  | ":$_grit_target_name", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a target that packages strings.xml generated from a grd file. | 
|  | # | 
|  | # If this target is included in the deps of an android resources/library/apk, | 
|  | # the strings.xml will be included with that target. | 
|  | # | 
|  | # Variables | 
|  | #  grit_output_dir: directory containing grit-generated files. | 
|  | #  generated_files: list of android resource files to package. | 
|  | # | 
|  | # Example | 
|  | #  java_strings_grd_prebuilt("foo_strings_grd") { | 
|  | #    grit_output_dir = "$root_gen_dir/foo/grit" | 
|  | #    generated_files = [ | 
|  | #      "values/strings.xml" | 
|  | #    ] | 
|  | #  } | 
|  | template("java_strings_grd_prebuilt") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | # JUnit tests use resource zip files. These must not be put in gen/ | 
|  | # directory or they will not be available to tester bots. | 
|  | _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) | 
|  | _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  | _build_config_target_name = "${target_name}__build_config" | 
|  |  | 
|  | write_build_config(_build_config_target_name) { | 
|  | type = "android_resources" | 
|  | build_config = _build_config | 
|  | resources_zip = _resources_zip | 
|  | } | 
|  |  | 
|  | zip(target_name) { | 
|  | forward_variables_from(invoker, [ "visibility" ]) | 
|  |  | 
|  | base_dir = invoker.grit_output_dir | 
|  | inputs = rebase_path(invoker.generated_files, ".", base_dir) | 
|  | output = _resources_zip | 
|  | deps = [ | 
|  | ":$_build_config_target_name", | 
|  | ] | 
|  | if (defined(invoker.deps)) { | 
|  | deps += invoker.deps | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a Java executable target | 
|  | # | 
|  | # Same as java_library, but also creates a wrapper script within | 
|  | # $root_out_dir/bin. | 
|  | # | 
|  | # Supports all variables of java_library(), plus: | 
|  | #   main_class: When specified, a wrapper script is created within | 
|  | #     $root_build_dir/bin to launch the binary with the given class as the | 
|  | #     entrypoint. | 
|  | #   wrapper_script_name: Filename for the wrapper script (default=target_name) | 
|  | #   wrapper_script_args: List of additional arguments for the wrapper script. | 
|  | # | 
|  | # Example | 
|  | #   java_binary("foo") { | 
|  | #     java_files = [ "org/chromium/foo/FooMain.java" ] | 
|  | #     deps = [ ":bar_java" ] | 
|  | #     main_class = "org.chromium.foo.FooMain" | 
|  | #   } | 
|  | # | 
|  | #   java_binary("foo") { | 
|  | #     jar_path = "lib/prebuilt.jar" | 
|  | #     deps = [ ":bar_java" ] | 
|  | #     main_class = "org.chromium.foo.FooMain" | 
|  | #   } | 
|  | template("java_binary") { | 
|  | java_library_impl(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  | type = "java_binary" | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a Java Annotation Processor. | 
|  | # | 
|  | # Supports all variables of java_library(), plus: | 
|  | #   jar_path: Path to a prebuilt jar. Mutually exclusive with java_files & | 
|  | #     srcjar_deps. | 
|  | #   main_class: The fully-quallified class name of the processor's entry | 
|  | #       point. | 
|  | # | 
|  | # Example | 
|  | #   java_annotation_processor("foo_processor") { | 
|  | #     java_files = [ "org/chromium/foo/FooProcessor.java" ] | 
|  | #     deps = [ ":bar_java" ] | 
|  | #     main_class = "org.chromium.foo.FooProcessor" | 
|  | #   } | 
|  | # | 
|  | #   java_annotation_processor("foo_processor") { | 
|  | #     jar_path = "lib/prebuilt.jar" | 
|  | #     main_class = "org.chromium.foo.FooMain" | 
|  | #   } | 
|  | # | 
|  | #   java_library("...") { | 
|  | #     annotation_processor_deps = [":foo_processor"] | 
|  | #   } | 
|  | # | 
|  | template("java_annotation_processor") { | 
|  | java_library_impl(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  | type = "java_annotation_processor" | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a Junit executable target | 
|  | # | 
|  | # This target creates an executable from java code for running as a junit test | 
|  | # suite. The executable will be in the output folder's /bin/ directory. | 
|  | # | 
|  | # Supports all variables of java_binary(). | 
|  | # | 
|  | # Example | 
|  | #   junit_binary("foo") { | 
|  | #     java_files = [ "org/chromium/foo/FooTest.java" ] | 
|  | #     deps = [ ":bar_java" ] | 
|  | #   } | 
|  | template("junit_binary") { | 
|  | testonly = true | 
|  |  | 
|  | _java_binary_target_name = "${target_name}__java_binary" | 
|  | _test_runner_target_name = "${target_name}__test_runner_script" | 
|  | _main_class = "org.chromium.testing.local.JunitTestMain" | 
|  |  | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  | _build_config_target_name = "${target_name}__build_config" | 
|  | _deps = [ | 
|  | "//testing/android/junit:junit_test_support", | 
|  | "//third_party/junit", | 
|  | "//third_party/mockito:mockito_java", | 
|  | "//third_party/robolectric:robolectric_all_java", | 
|  |  | 
|  | # This dep is required if any deps require android (but it doesn't hurt | 
|  | # to add it regardless) and is used by bytecode rewritten classes. | 
|  | "//build/android/buildhooks:build_hooks_android_impl_java", | 
|  | ] | 
|  | if (defined(invoker.deps)) { | 
|  | _deps += invoker.deps | 
|  | } | 
|  |  | 
|  | _prepare_resources_target = "${target_name}__prepare_resources" | 
|  | prepare_resources(_prepare_resources_target) { | 
|  | deps = _deps + [ ":$_build_config_target_name" ] | 
|  | build_config = _build_config | 
|  | srcjar_path = "${target_gen_dir}/${target_name}.srcjar" | 
|  | if (defined(invoker.package_name)) { | 
|  | custom_package = invoker.package_name | 
|  | } | 
|  | if (defined(invoker.android_manifest_path)) { | 
|  | android_manifest = invoker.android_manifest_path | 
|  | } else { | 
|  | android_manifest = "//build/android/AndroidManifest.xml" | 
|  | } | 
|  | } | 
|  |  | 
|  | java_library_impl(_java_binary_target_name) { | 
|  | forward_variables_from(invoker, "*", [ "deps" ]) | 
|  | type = "junit_binary" | 
|  | main_target_name = invoker.target_name | 
|  |  | 
|  | # Robolectric can handle deps that set !supports_android as well those | 
|  | # that set requires_android. | 
|  | bypass_platform_checks = true | 
|  | deps = _deps | 
|  | testonly = true | 
|  | main_class = _main_class | 
|  | wrapper_script_name = "helper/$main_target_name" | 
|  | if (!defined(srcjar_deps)) { | 
|  | srcjar_deps = [] | 
|  | } | 
|  | srcjar_deps += [ | 
|  | ":$_prepare_resources_target", | 
|  |  | 
|  | # This dep is required for any targets that depend on //base:base_java. | 
|  | "//base:base_build_config_gen", | 
|  | ] | 
|  | } | 
|  |  | 
|  | test_runner_script(_test_runner_target_name) { | 
|  | test_name = invoker.target_name | 
|  | test_suite = invoker.target_name | 
|  | test_type = "junit" | 
|  | ignore_all_data_deps = true | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "android_manifest_path", | 
|  | "package_name", | 
|  | ]) | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | public_deps = [ | 
|  | ":$_build_config_target_name", | 
|  | ":$_java_binary_target_name", | 
|  | ":$_test_runner_target_name", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a java library target | 
|  | # | 
|  | # Variables | 
|  | #   deps: Specifies the dependencies of this target. Java targets in this list | 
|  | #     will be added to the javac classpath. | 
|  | #   annotation_processor_deps: List of java_annotation_processor targets to | 
|  | #     use when compiling. | 
|  | # | 
|  | #   jar_path: Path to a prebuilt jar. Mutually exclusive with java_files & | 
|  | #     srcjar_deps. | 
|  | #   java_files: List of .java files included in this library. | 
|  | #   srcjar_deps: List of srcjar dependencies. The .java files in the srcjars | 
|  | #     will be added to java_files and be included in this library. | 
|  | # | 
|  | #   input_jars_paths: A list of paths to the jars that should be included | 
|  | #     in the compile-time classpath. These are in addition to library .jars | 
|  | #     that appear in deps. | 
|  | #   classpath_deps: Deps that should added to the classpath for this target, | 
|  | #     but not linked into the apk (use this for annotation processors). | 
|  | # | 
|  | #   chromium_code: If true, extra analysis warning/errors will be enabled. | 
|  | #   enable_errorprone: If true, enables the errorprone compiler. | 
|  | #   enable_incremental_javac_override: Overrides the global | 
|  | #     enable_incremental_javac. | 
|  | # | 
|  | #   jar_excluded_patterns: List of patterns of .class files to exclude. | 
|  | #   jar_included_patterns: List of patterns of .class files to include. | 
|  | #     When omitted, all classes not matched by jar_excluded_patterns are | 
|  | #     included. When specified, all non-matching .class files are stripped. | 
|  | # | 
|  | #   output_name: File name for the output .jar (not including extension). | 
|  | #     Defaults to the input .jar file name. | 
|  | # | 
|  | #   proguard_configs: List of proguard configs to use in final apk step for | 
|  | #     any apk that depends on this library. | 
|  | # | 
|  | #   supports_android: If true, Android targets (android_library, android_apk) | 
|  | #     may depend on this target. Note: if true, this target must only use the | 
|  | #     subset of Java available on Android. | 
|  | #   bypass_platform_checks: Disables checks about cross-platform (Java/Android) | 
|  | #     dependencies for this target. This will allow depending on an | 
|  | #     android_library target, for example. | 
|  | # | 
|  | #   additional_jar_files: Use to package additional files (Java resources) | 
|  | #     into the output jar. Pass a list of length-2 lists with format: | 
|  | #         [ [ path_to_file, path_to_put_in_jar ] ] | 
|  | # | 
|  | #   javac_args: Additional arguments to pass to javac. | 
|  | # | 
|  | #   data_deps, testonly | 
|  | # | 
|  | # Example | 
|  | #   java_library("foo_java") { | 
|  | #     java_files = [ | 
|  | #       "org/chromium/foo/Foo.java", | 
|  | #       "org/chromium/foo/FooInterface.java", | 
|  | #       "org/chromium/foo/FooService.java", | 
|  | #     ] | 
|  | #     deps = [ | 
|  | #       ":bar_java" | 
|  | #     ] | 
|  | #     srcjar_deps = [ | 
|  | #       ":foo_generated_enum" | 
|  | #     ] | 
|  | #     jar_excluded_patterns = [ | 
|  | #       "*/FooService.class", "org/chromium/FooService\$*.class" | 
|  | #     ] | 
|  | #   } | 
|  | template("java_library") { | 
|  | java_library_impl(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  | type = "java_library" | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare a java library target for a prebuilt jar | 
|  | # | 
|  | # Supports all variables of java_library(). | 
|  | # | 
|  | # Example | 
|  | #   java_prebuilt("foo_java") { | 
|  | #     jar_path = "foo.jar" | 
|  | #     deps = [ | 
|  | #       ":foo_resources", | 
|  | #       ":bar_java" | 
|  | #     ] | 
|  | #   } | 
|  | template("java_prebuilt") { | 
|  | java_library_impl(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  | type = "java_library" | 
|  | } | 
|  | } | 
|  |  | 
|  | # Combines all dependent .jar files into a single .jar file. | 
|  | # | 
|  | # Variables: | 
|  | #   output: Path to the output jar. | 
|  | #   dex_path: Path to dex()'ed output (optional). | 
|  | #   override_build_config: Use a pre-existing .build_config. Must be of type | 
|  | #     "apk". | 
|  | #   use_interface_jars: Use all dependent interface .jars rather than | 
|  | #     implementation .jars. | 
|  | #   use_unprocessed_jars: Use unprocessed / undesugared .jars. | 
|  | #   direct_deps_only: Do not recurse on deps. | 
|  | #   proguard_enabled: Whether to run ProGuard on resulting jar. | 
|  | #   proguard_configs: List of proguard configs. | 
|  | #   proguard_jar_path: The path to proguard.jar you wish to use. If undefined, | 
|  | #     the proguard used will be the checked in one in //third_party/proguard. | 
|  | #   alternative_android_sdk_jar: System jar to use when proguard is enabled. | 
|  | # | 
|  | # Example | 
|  | #   dist_jar("lib_fatjar") { | 
|  | #     deps = [ ":my_java_lib" ] | 
|  | #     output = "$root_build_dir/MyLibrary.jar" | 
|  | #   } | 
|  | #   dist_jar("sideloaded_dex") { | 
|  | #     deps = [ ":my_java_lib" ] | 
|  | #     output = "$root_build_dir/MyLibrary.jar" | 
|  | #     dex_path = "$root_build_dir/MyLibrary.dex" | 
|  | #   } | 
|  | template("dist_jar") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  | _supports_android = | 
|  | !defined(invoker.supports_android) || invoker.supports_android | 
|  | _requires_android = | 
|  | defined(invoker.requires_android) && invoker.requires_android | 
|  | _proguard_enabled = | 
|  | defined(invoker.proguard_enabled) && invoker.proguard_enabled | 
|  | _use_interface_jars = | 
|  | defined(invoker.use_interface_jars) && invoker.use_interface_jars | 
|  | _use_unprocessed_jars = | 
|  | defined(invoker.use_unprocessed_jars) && invoker.use_unprocessed_jars | 
|  | _direct_deps_only = | 
|  | defined(invoker.direct_deps_only) && invoker.direct_deps_only | 
|  | assert(!(_proguard_enabled && _use_interface_jars), | 
|  | "Cannot set both proguard_enabled and use_interface_jars") | 
|  | assert(!(_proguard_enabled && _direct_deps_only), | 
|  | "Cannot set both proguard_enabled and direct_deps_only") | 
|  | assert(!(_use_unprocessed_jars && _use_interface_jars), | 
|  | "Cannot set both use_interface_jars and use_unprocessed_jars") | 
|  |  | 
|  | _jar_target_name = target_name | 
|  | if (defined(invoker.dex_path)) { | 
|  | if (_proguard_enabled) { | 
|  | _jar_target_name = "${target_name}__proguard" | 
|  | } else { | 
|  | _jar_target_name = "${target_name}__dist_jar" | 
|  | } | 
|  | } | 
|  |  | 
|  | _deps = [] | 
|  | if (defined(invoker.deps)) { | 
|  | _deps = invoker.deps | 
|  | } | 
|  | _enable_build_hooks = | 
|  | _supports_android && | 
|  | (!defined(invoker.no_build_hooks) || !invoker.no_build_hooks) | 
|  | if (_enable_build_hooks && _requires_android) { | 
|  | _deps += [ "//build/android/buildhooks:build_hooks_android_impl_java" ] | 
|  | } | 
|  |  | 
|  | if (defined(invoker.override_build_config)) { | 
|  | _build_config = invoker.override_build_config | 
|  | } else { | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  | _build_config_target_name = "${target_name}__build_config" | 
|  |  | 
|  | write_build_config(_build_config_target_name) { | 
|  | type = "dist_jar" | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "proguard_enabled", | 
|  | "proguard_configs", | 
|  | ]) | 
|  | supports_android = _supports_android | 
|  | requires_android = _requires_android | 
|  | possible_config_deps = _deps | 
|  | build_config = _build_config | 
|  | } | 
|  |  | 
|  | _deps += [ ":$_build_config_target_name" ] | 
|  | } | 
|  |  | 
|  | _rebased_build_config = rebase_path(_build_config, root_build_dir) | 
|  | if (_proguard_enabled) { | 
|  | proguard(_jar_target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "alternative_android_sdk_jar", | 
|  | "data", | 
|  | "proguard_jar_path", | 
|  | ]) | 
|  | deps = _deps | 
|  | inputs = [ | 
|  | _build_config, | 
|  | ] | 
|  |  | 
|  | # Although these will be listed as deps in the depfile, they must also | 
|  | # appear here so that "gn analyze" knows about them. | 
|  | # https://crbug.com/827197 | 
|  | if (defined(invoker.proguard_configs)) { | 
|  | inputs += invoker.proguard_configs | 
|  | } | 
|  |  | 
|  | output_jar_path = invoker.output | 
|  | args = [ | 
|  | "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", | 
|  | "--input-paths=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)", | 
|  | "--classpath=@FileArg($_rebased_build_config:deps_info:proguard_all_extra_jars)", | 
|  | ] | 
|  | if (defined(invoker.proguard_config_exclusions)) { | 
|  | _rebased_proguard_config_exclusions = | 
|  | rebase_path(invoker.proguard_config_exclusions, root_build_dir) | 
|  | args += [ | 
|  | "--proguard-config-exclusions=$_rebased_proguard_config_exclusions", | 
|  | ] | 
|  | } | 
|  | } | 
|  | } else { | 
|  | action(_jar_target_name) { | 
|  | forward_variables_from(invoker, [ "data" ]) | 
|  | script = "//build/android/gyp/create_dist_jar.py" | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  | deps = _deps | 
|  |  | 
|  | inputs = [ | 
|  | _build_config, | 
|  | ] | 
|  |  | 
|  | outputs = [ | 
|  | invoker.output, | 
|  | ] | 
|  |  | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--output", | 
|  | rebase_path(invoker.output, root_build_dir), | 
|  | ] | 
|  |  | 
|  | if (_direct_deps_only) { | 
|  | if (_use_interface_jars) { | 
|  | args += [ "--jars=@FileArg($_rebased_build_config:javac:interface_classpath)" ] | 
|  | } else if (_use_unprocessed_jars) { | 
|  | args += | 
|  | [ "--jars=@FileArg($_rebased_build_config:javac:classpath)" ] | 
|  | } else { | 
|  | assert( | 
|  | false, | 
|  | "direct_deps_only does not work without use_interface_jars or use_unprocessed_jars") | 
|  | } | 
|  | } else { | 
|  | if (_use_interface_jars) { | 
|  | args += [ "--jars=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ] | 
|  | } else if (_use_unprocessed_jars) { | 
|  | args += [ "--jars=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ] | 
|  | } else { | 
|  | args += [ "--jars=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)" ] | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | if (defined(invoker.dex_path)) { | 
|  | dex(target_name) { | 
|  | deps = [ | 
|  | ":$_jar_target_name", | 
|  | ] | 
|  | input_jars = [ invoker.output ] | 
|  | output = invoker.dex_path | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Creates an Android .aar library. | 
|  | # | 
|  | # Currently supports: | 
|  | #   * AndroidManifest.xml | 
|  | #   * classes.jar | 
|  | #   * jni/ | 
|  | #   * res/ | 
|  | #   * R.txt | 
|  | #   * proguard.txt | 
|  | # Does not yet support: | 
|  | #   * public.txt | 
|  | #   * annotations.zip | 
|  | #   * assets/ | 
|  | # See: https://developer.android.com/studio/projects/android-library.html#aar-contents | 
|  | # | 
|  | # Variables: | 
|  | #   output: Path to the output .aar. | 
|  | #   proguard_configs: List of proguard configs (optional). | 
|  | #   android_manifest: Path to AndroidManifest.xml (optional). | 
|  | #   native_libraries: list of native libraries (optional). | 
|  | #   direct_deps_only: Do not recurse on deps. (optional, defaults false). | 
|  | # | 
|  | # Example | 
|  | #   dist_aar("my_aar") { | 
|  | #     deps = [ ":my_java_lib" ] | 
|  | #     output = "$root_build_dir/MyLibrary.aar" | 
|  | #   } | 
|  | template("dist_aar") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | _deps = [] | 
|  | if (defined(invoker.deps)) { | 
|  | _deps = invoker.deps | 
|  | } | 
|  |  | 
|  | _direct_deps_only = | 
|  | defined(invoker.direct_deps_only) && invoker.direct_deps_only | 
|  |  | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  | _build_config_target_name = "${target_name}__build_config" | 
|  |  | 
|  | write_build_config(_build_config_target_name) { | 
|  | type = "dist_aar" | 
|  | forward_variables_from(invoker, [ "proguard_configs" ]) | 
|  | possible_config_deps = _deps | 
|  | supports_android = true | 
|  | requires_android = true | 
|  | build_config = _build_config | 
|  | } | 
|  |  | 
|  | _deps += [ ":$_build_config_target_name" ] | 
|  |  | 
|  | _rebased_build_config = rebase_path(_build_config, root_build_dir) | 
|  |  | 
|  | action(target_name) { | 
|  | forward_variables_from(invoker, [ "data" ]) | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  | deps = _deps | 
|  | script = "//build/android/gyp/dist_aar.py" | 
|  |  | 
|  | inputs = [ | 
|  | _build_config, | 
|  | ] | 
|  |  | 
|  | # Although these will be listed as deps in the depfile, they must also | 
|  | # appear here so that "gn analyze" knows about them. | 
|  | # https://crbug.com/827197 | 
|  | if (defined(invoker.proguard_configs)) { | 
|  | inputs += invoker.proguard_configs | 
|  | } | 
|  |  | 
|  | outputs = [ | 
|  | invoker.output, | 
|  | ] | 
|  |  | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--output", | 
|  | rebase_path(invoker.output, root_build_dir), | 
|  | "--dependencies-res-zips=@FileArg($_rebased_build_config:resources:dependency_zips)", | 
|  | "--r-text-files=@FileArg($_rebased_build_config:resources:extra_r_text_files)", | 
|  | "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", | 
|  | ] | 
|  | if (_direct_deps_only) { | 
|  | args += [ "--jars=@FileArg($_rebased_build_config:javac:classpath)" ] | 
|  | } else { | 
|  | args += [ "--jars=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ] | 
|  | } | 
|  | if (defined(invoker.android_manifest)) { | 
|  | args += [ | 
|  | "--android-manifest", | 
|  | rebase_path(invoker.android_manifest, root_build_dir), | 
|  | ] | 
|  | } | 
|  | if (defined(invoker.native_libraries) && invoker.native_libraries != []) { | 
|  | inputs += invoker.native_libraries | 
|  | _rebased_native_libraries = | 
|  | rebase_path(invoker.native_libraries, root_build_dir) | 
|  |  | 
|  | args += [ | 
|  | "--native-libraries=$_rebased_native_libraries", | 
|  | "--abi=$android_app_abi", | 
|  | ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android library target | 
|  | # | 
|  | # This target creates an Android library containing java code and Android | 
|  | # resources. | 
|  | # | 
|  | # Supports all variables of java_library(), plus: | 
|  | #   android_manifest_for_lint: Path to AndroidManifest.xml (optional). This | 
|  | #     manifest will be used by Android lint, but will not be merged into apks. | 
|  | #     To have a manifest merged, add it to an android_resources() target. | 
|  | #   deps: In addition to defining java deps, this can also include | 
|  | #     android_assets() and android_resources() targets. | 
|  | #   dex_path: If set, the resulting .dex.jar file will be placed under this | 
|  | #     path. | 
|  | #   alternative_android_sdk_ijar: if set, the given android_sdk_ijar file | 
|  | #     replaces the default android_sdk_ijar. | 
|  | #   alternative_android_sdk_ijar_dep: the target that generates | 
|  | #      alternative_android_sdk_ijar, must be set if alternative_android_sdk_ijar | 
|  | #      is used. | 
|  | #   alternative_android_sdk_jar: actual jar corresponding to | 
|  | #      alternative_android_sdk_ijar, must be set if alternative_android_sdk_ijar | 
|  | #      is used. | 
|  | # | 
|  | # Example | 
|  | #   android_library("foo_java") { | 
|  | #     java_files = [ | 
|  | #       "android/org/chromium/foo/Foo.java", | 
|  | #       "android/org/chromium/foo/FooInterface.java", | 
|  | #       "android/org/chromium/foo/FooService.java", | 
|  | #     ] | 
|  | #     deps = [ | 
|  | #       ":bar_java" | 
|  | #     ] | 
|  | #     srcjar_deps = [ | 
|  | #       ":foo_generated_enum" | 
|  | #     ] | 
|  | #     jar_excluded_patterns = [ | 
|  | #       "*/FooService.class", "org/chromium/FooService\$*.class" | 
|  | #     ] | 
|  | #   } | 
|  | template("android_library") { | 
|  | java_library(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  |  | 
|  | if (defined(alternative_android_sdk_ijar)) { | 
|  | assert(defined(alternative_android_sdk_ijar_dep)) | 
|  | assert(defined(alternative_android_sdk_jar)) | 
|  | } | 
|  |  | 
|  | supports_android = true | 
|  | requires_android = true | 
|  |  | 
|  | if (!defined(jar_excluded_patterns)) { | 
|  | jar_excluded_patterns = [] | 
|  | } | 
|  | jar_excluded_patterns += [ | 
|  | "*/R.class", | 
|  | "*/R\$*.class", | 
|  | "*/Manifest.class", | 
|  | "*/Manifest\$*.class", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android library target for a prebuilt jar | 
|  | # | 
|  | # This target creates an Android library containing java code and Android | 
|  | # resources. | 
|  | # | 
|  | # Supports all variables of android_library(). | 
|  | # | 
|  | # Example | 
|  | #   android_java_prebuilt("foo_java") { | 
|  | #     jar_path = "foo.jar" | 
|  | #     deps = [ | 
|  | #       ":foo_resources", | 
|  | #       ":bar_java" | 
|  | #     ] | 
|  | #   } | 
|  | template("android_java_prebuilt") { | 
|  | android_library(target_name) { | 
|  | forward_variables_from(invoker, "*") | 
|  | } | 
|  | } | 
|  |  | 
|  | # Creates org/chromium/base/BuildConfig.java | 
|  | # This doesn't really belong in //build since it genates a file for //base. | 
|  | # However, we don't currently have a better way to include this file in all | 
|  | # apks that depend on //base:base_java. | 
|  | # | 
|  | # Variables: | 
|  | #   use_final_fields: True to use final fields. All other variables are | 
|  | #       ignored when this is false. | 
|  | #   build_config: Path to build_config used for locale list | 
|  | #   enable_multidex: Value for ENABLE_MULTIDEX. | 
|  | #   firebase_app_id: Value for FIREBASE_APP_ID. | 
|  | # | 
|  | template("generate_build_config_srcjar") { | 
|  | java_cpp_template(target_name) { | 
|  | package_path = "org/chromium/base" | 
|  | sources = [ | 
|  | "//base/android/java/templates/BuildConfig.template", | 
|  | ] | 
|  | defines = [] | 
|  |  | 
|  | # TODO(agrieve): These two are not target-specific and should be moved | 
|  | #     to BuildHooks.java. | 
|  | # Set these even when !use_final_fields so that they have correct default | 
|  | # values withnin junit_binary(). | 
|  | if (is_java_debug || dcheck_always_on) { | 
|  | defines += [ "_DCHECK_IS_ON" ] | 
|  | } | 
|  | if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { | 
|  | defines += [ "_IS_UBSAN" ] | 
|  | } | 
|  |  | 
|  | if (invoker.use_final_fields) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "testonly", | 
|  | ]) | 
|  | defines += [ "USE_FINAL" ] | 
|  | if (invoker.enable_multidex) { | 
|  | defines += [ "ENABLE_MULTIDEX" ] | 
|  | } | 
|  | inputs = [ | 
|  | invoker.build_config, | 
|  | ] | 
|  | _rebased_build_config = rebase_path(invoker.build_config) | 
|  | defines += [ | 
|  | "COMPRESSED_LOCALE_LIST=" + | 
|  | "@FileArg($_rebased_build_config:compressed_locales_java_list)", | 
|  | "UNCOMPRESSED_LOCALE_LIST=" + | 
|  | "@FileArg($_rebased_build_config:uncompressed_locales_java_list)", | 
|  | ] | 
|  | if (defined(invoker.firebase_app_id)) { | 
|  | defines += [ "_FIREBASE_APP_ID=${invoker.firebase_app_id}" ] | 
|  | } | 
|  | if (defined(invoker.resources_version_variable)) { | 
|  | defines += [ | 
|  | "_RESOURCES_VERSION_VARIABLE=${invoker.resources_version_variable}", | 
|  | ] | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android apk target | 
|  | # | 
|  | # This target creates an Android APK containing java code, resources, assets, | 
|  | # and (possibly) native libraries. | 
|  | # | 
|  | # Supports all variables of android_library(), plus: | 
|  | #   android_manifest: Path to AndroidManifest.xml. | 
|  | #   android_manifest_dep: Target that generates AndroidManifest (if applicable) | 
|  | #   png_to_webp: If true, pngs (with the exception of 9-patch) are | 
|  | #     converted to webp during resource packaging. | 
|  | #   dist_ijar_path: Path to create "${target_name}_dist_ijar" target | 
|  | #     (used by instrumentation_test_apk). | 
|  | #   apk_name: Name for final apk. | 
|  | #   final_apk_path: Path to final built apk. Default is | 
|  | #     $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name. | 
|  | #   loadable_modules: List of paths to native libraries to include. Different | 
|  | #     from |shared_libraries| in that: | 
|  | #       * dependencies of this .so are not automatically included | 
|  | #       * ".cr.so" is never added | 
|  | #       * they are not side-loaded for _incremental targets. | 
|  | #       * load_library_from_apk, use_chromium_linker, | 
|  | #         and enable_relocation_packing do not apply | 
|  | #     Use this instead of shared_libraries when you are going to load the library | 
|  | #     conditionally, and only when shared_libraries doesn't work for you. | 
|  | #   shared_libraries: List shared_library targets to bundle. If these | 
|  | #     libraries depend on other shared_library targets, those dependencies will | 
|  | #     also be included in the apk (e.g. for is_component_build). | 
|  | #   secondary_abi_shared_libraries: secondary abi shared_library targets to | 
|  | #     bundle. If these libraries depend on other shared_library targets, those | 
|  | #     dependencies will also be included in the apk (e.g. for is_component_build). | 
|  | #   native_lib_placeholders: List of placeholder filenames to add to the apk | 
|  | #     (optional). | 
|  | #   secondary_native_lib_placeholders: List of placeholder filenames to add to | 
|  | #     the apk for the secondary ABI (optional). | 
|  | #   apk_under_test: For an instrumentation test apk, this is the target of the | 
|  | #     tested apk. | 
|  | #   write_asset_list: Adds an extra file to the assets, which contains a list of | 
|  | #     all other asset files. | 
|  | #   generate_buildconfig_java: If defined and false, skip generating the | 
|  | #     BuildConfig java class describing the build configuration. The default | 
|  | #     is true for non-test APKs. | 
|  | #   firebase_app_id: The value for BuildConfig.FIREBASE_APP_ID (optional). | 
|  | #     Identifier is sent with crash reports to enable Java stack deobfuscation. | 
|  | #   requires_sdk_api_level_23: If defined and true, the apk is intended for | 
|  | #     installation only on Android M or later. In these releases the system | 
|  | #     linker does relocation unpacking, so we can enable it unconditionally. | 
|  | #   secondary_native_libs (deprecated): The path of native libraries for secondary | 
|  | #     app abi. | 
|  | #   proguard_jar_path: The path to proguard.jar you wish to use. If undefined, | 
|  | #     the proguard used will be the checked in one in //third_party/proguard. | 
|  | #   never_incremental: If true, |incremental_apk_by_default| will be ignored. | 
|  | #   aapt_locale_whitelist: If set, all locales not in this list will be | 
|  | #     stripped from resources.arsc. | 
|  | #   exclude_xxxhdpi: Causes all drawable-xxxhdpi images to be excluded | 
|  | #     (mipmaps are still included). | 
|  | #   xxxhdpi_whitelist: A list of globs used when exclude_xxxhdpi=true. Files | 
|  | #     that match this whitelist will still be included. | 
|  | #   shared_resources: True if this is a runtime shared library APK, like | 
|  | #     the system_webview_apk target. Ensures that its resources can be | 
|  | #     used by the loading application process. | 
|  | #   app_as_shared_lib: True if this is a regular application apk that can | 
|  | #     also serve as a runtime shared library, like the monochrome_public_apk | 
|  | #     target. Ensures that the resources are usable both by the APK running | 
|  | #     as an application, or by another process that loads it at runtime. | 
|  | #   shared_resources_whitelist_target: Optional name of a target specifying | 
|  | #     an input R.txt file that lists the resources that can be exported | 
|  | #     by the APK when shared_resources or app_as_shared_lib is defined. | 
|  | # | 
|  | # Example | 
|  | #   android_apk("foo_apk") { | 
|  | #     android_manifest = "AndroidManifest.xml" | 
|  | #     java_files = [ | 
|  | #       "android/org/chromium/foo/FooApplication.java", | 
|  | #       "android/org/chromium/foo/FooActivity.java", | 
|  | #     ] | 
|  | #     deps = [ | 
|  | #       ":foo_support_java" | 
|  | #       ":foo_resources" | 
|  | #     ] | 
|  | #     srcjar_deps = [ | 
|  | #       ":foo_generated_enum" | 
|  | #     ] | 
|  | #     shared_libraries = [ | 
|  | #       ":my_shared_lib", | 
|  | #     ] | 
|  | #   } | 
|  | template("android_apk") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | assert(defined(invoker.final_apk_path) || defined(invoker.apk_name)) | 
|  | assert(defined(invoker.android_manifest)) | 
|  | _gen_dir = "$target_gen_dir/$target_name" | 
|  | _base_path = "$_gen_dir/$target_name" | 
|  | _build_config = "$target_gen_dir/$target_name.build_config" | 
|  | _build_config_target = "${target_name}__build_config" | 
|  |  | 
|  | # JUnit tests use resource zip files. These must not be put in gen/ | 
|  | # directory or they will not be available to tester bots. | 
|  | _jar_path = "$_base_path.jar" | 
|  | _lib_dex_path = "$_base_path.dex.jar" | 
|  | _rebased_lib_dex_path = rebase_path(_lib_dex_path, root_build_dir) | 
|  | _template_name = target_name | 
|  |  | 
|  | _enable_multidex = | 
|  | defined(invoker.enable_multidex) && invoker.enable_multidex | 
|  | if (_enable_multidex) { | 
|  | _final_dex_path = "$_gen_dir/classes.dex.zip" | 
|  | } else { | 
|  | _final_dex_path = "$_gen_dir/classes.dex" | 
|  | } | 
|  | _final_dex_target_name = "${_template_name}__final_dex" | 
|  |  | 
|  | if (defined(invoker.final_apk_path)) { | 
|  | _final_apk_path = invoker.final_apk_path | 
|  | } else { | 
|  | _final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk" | 
|  | } | 
|  | _final_apk_path_no_ext_list = | 
|  | process_file_template([ _final_apk_path ], | 
|  | "{{source_dir}}/{{source_name_part}}") | 
|  | _final_apk_path_no_ext = _final_apk_path_no_ext_list[0] | 
|  | assert(_final_apk_path_no_ext != "")  # Mark as used. | 
|  |  | 
|  | # resource_sizes.py needs to be able to find the unpacked resources.arsc file based on apk name. | 
|  | _packaged_resources_path = | 
|  | "$root_gen_dir/arsc/" + | 
|  | rebase_path(_final_apk_path_no_ext, root_build_dir) + ".ap_" | 
|  |  | 
|  | _incremental_install_json_path = | 
|  | "$target_gen_dir/$target_name.incremental.json" | 
|  |  | 
|  | _version_code = android_default_version_code | 
|  | if (defined(invoker.version_code)) { | 
|  | _version_code = invoker.version_code | 
|  | } | 
|  |  | 
|  | _version_name = android_default_version_name | 
|  | if (defined(invoker.version_name)) { | 
|  | _version_name = invoker.version_name | 
|  | } | 
|  | _keystore_path = android_keystore_path | 
|  | _keystore_name = android_keystore_name | 
|  | _keystore_password = android_keystore_password | 
|  |  | 
|  | if (defined(invoker.keystore_path)) { | 
|  | _keystore_path = invoker.keystore_path | 
|  | _keystore_name = invoker.keystore_name | 
|  | _keystore_password = invoker.keystore_password | 
|  | } | 
|  |  | 
|  | _deps = [] | 
|  | if (defined(invoker.deps)) { | 
|  | _deps = invoker.deps | 
|  | set_sources_assignment_filter([ "*manifest*" ]) | 
|  | sources = _deps | 
|  | set_sources_assignment_filter([]) | 
|  | if (sources != _deps) { | 
|  | _bad_deps = _deps - sources | 
|  | assert( | 
|  | false, | 
|  | "Possible manifest-generating dep found in deps. Use android_manifest_dep for this instead. Found: $_bad_deps") | 
|  | } | 
|  | sources = [] | 
|  | } | 
|  |  | 
|  | _srcjar_deps = [] | 
|  | if (defined(invoker.srcjar_deps)) { | 
|  | _srcjar_deps = invoker.srcjar_deps | 
|  | } | 
|  |  | 
|  | _use_build_hooks = | 
|  | !defined(invoker.no_build_hooks) || !invoker.no_build_hooks | 
|  | if (defined(invoker.build_hooks_android_impl_deps)) { | 
|  | assert(_use_build_hooks, | 
|  | "Cannot set no_build_hooks and build_hooks_android_impl_deps at " + | 
|  | "the same time") | 
|  | _deps += invoker.build_hooks_android_impl_deps | 
|  | } else if (_use_build_hooks) { | 
|  | _deps += [ "//build/android/buildhooks:build_hooks_android_impl_java" ] | 
|  | } | 
|  |  | 
|  | _android_root_manifest_deps = [] | 
|  | if (defined(invoker.android_manifest_dep)) { | 
|  | _android_root_manifest_deps = [ invoker.android_manifest_dep ] | 
|  | } | 
|  | _android_root_manifest = invoker.android_manifest | 
|  |  | 
|  | _use_chromium_linker = | 
|  | defined(invoker.use_chromium_linker) && invoker.use_chromium_linker | 
|  | _pack_relocations = | 
|  | defined(invoker.pack_relocations) && invoker.pack_relocations | 
|  |  | 
|  | _load_library_from_apk = | 
|  | defined(invoker.load_library_from_apk) && invoker.load_library_from_apk | 
|  | _requires_sdk_api_level_23 = defined(invoker.requires_sdk_api_level_23) && | 
|  | invoker.requires_sdk_api_level_23 | 
|  |  | 
|  | assert(_use_chromium_linker || true)  # Mark as used. | 
|  | assert(_requires_sdk_api_level_23 || true) | 
|  | assert(!_pack_relocations || !use_lld, | 
|  | "Use //build/config/android:lld_pack_relocations to pack " + | 
|  | "relocations when use_lld=true.") | 
|  | assert(!_pack_relocations || _use_chromium_linker || | 
|  | _requires_sdk_api_level_23, | 
|  | "pack_relocations requires either use_chromium_linker " + | 
|  | "or requires_sdk_api_level_23") | 
|  | assert(!_load_library_from_apk || _use_chromium_linker || | 
|  | _requires_sdk_api_level_23, | 
|  | "load_library_from_apk requires use_chromium_linker " + | 
|  | "or requires_sdk_api_level_23") | 
|  |  | 
|  | # The dependency that makes the chromium linker, if any is needed. | 
|  | _native_libs_deps = [] | 
|  | _shared_libraries_is_valid = | 
|  | defined(invoker.shared_libraries) && invoker.shared_libraries != [] | 
|  | _secondary_abi_native_libs_deps = [] | 
|  | assert(_secondary_abi_native_libs_deps == [])  # mark as used. | 
|  | _secondary_abi_shared_libraries_is_valid = | 
|  | defined(invoker.secondary_abi_shared_libraries) && | 
|  | invoker.secondary_abi_shared_libraries != [] | 
|  |  | 
|  | if (is_component_build || is_asan) { | 
|  | if (_shared_libraries_is_valid) { | 
|  | _native_libs_deps += [ "//build/android:cpplib_stripped" ] | 
|  | } | 
|  | if (_secondary_abi_shared_libraries_is_valid) { | 
|  | _secondary_abi_native_libs_deps += [ | 
|  | "//build/android:cpplib_stripped($android_secondary_abi_toolchain)", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | if (_shared_libraries_is_valid) { | 
|  | _native_libs_deps += invoker.shared_libraries | 
|  |  | 
|  | # To determine the filenames of all dependent shared libraries, write the | 
|  | # runtime deps of |shared_libraries| to a file during "gn gen". | 
|  | # write_build_config.py will then grep this file for *.so to obtain the | 
|  | # complete list. | 
|  | _runtime_deps_file = | 
|  | "$target_gen_dir/${_template_name}.native.runtimedeps" | 
|  | group("${_template_name}__runtime_deps") { | 
|  | deps = _native_libs_deps | 
|  | write_runtime_deps = _runtime_deps_file | 
|  | } | 
|  |  | 
|  | _native_lib_version_rule = "" | 
|  | if (defined(invoker.native_lib_version_rule)) { | 
|  | _native_lib_version_rule = invoker.native_lib_version_rule | 
|  | } | 
|  | _native_lib_version_arg = "\"\"" | 
|  | if (defined(invoker.native_lib_version_arg)) { | 
|  | _native_lib_version_arg = invoker.native_lib_version_arg | 
|  | } | 
|  | } else { | 
|  | # Must exist for instrumentation_test_apk() to depend on. | 
|  | group("${_template_name}__runtime_deps") { | 
|  | } | 
|  | } | 
|  |  | 
|  | if (_secondary_abi_shared_libraries_is_valid) { | 
|  | _secondary_abi_native_libs_deps += invoker.secondary_abi_shared_libraries | 
|  |  | 
|  | # To determine the filenames of all dependent shared libraries, write the | 
|  | # runtime deps of |shared_libraries| to a file during "gn gen". | 
|  | # write_build_config.py will then grep this file for *.so to obtain the | 
|  | # complete list. | 
|  | _secondary_abi_runtime_deps_file = | 
|  | "$target_gen_dir/${_template_name}.secondary.abi.native.runtimedeps" | 
|  | group("${_template_name}__secondary_abi__runtime_deps") { | 
|  | deps = _secondary_abi_native_libs_deps | 
|  | write_runtime_deps = _secondary_abi_runtime_deps_file | 
|  | } | 
|  | } else { | 
|  | # Must exist for instrumentation_test_apk() to depend on. | 
|  | group("${_template_name}__secondary_abi_runtime_deps") { | 
|  | } | 
|  | } | 
|  |  | 
|  | _rebased_build_config = rebase_path(_build_config, root_build_dir) | 
|  |  | 
|  | _generate_buildconfig_java = !defined(invoker.apk_under_test) | 
|  | if (defined(invoker.generate_buildconfig_java)) { | 
|  | _generate_buildconfig_java = invoker.generate_buildconfig_java | 
|  | } | 
|  |  | 
|  | _proguard_enabled = | 
|  | defined(invoker.proguard_enabled) && invoker.proguard_enabled | 
|  | if (_proguard_enabled) { | 
|  | _proguard_output_jar_path = "$_base_path.proguard.jar" | 
|  | } | 
|  |  | 
|  | _incremental_allowed = | 
|  | !(defined(invoker.never_incremental) && invoker.never_incremental) | 
|  |  | 
|  | _android_manifest = | 
|  | "$target_gen_dir/${_template_name}_manifest/AndroidManifest.xml" | 
|  | _merge_manifest_target = "${_template_name}__merge_manifests" | 
|  | merge_manifests(_merge_manifest_target) { | 
|  | input_manifest = _android_root_manifest | 
|  | output_manifest = _android_manifest | 
|  | build_config = _build_config | 
|  | deps = _android_root_manifest_deps + [ ":$_build_config_target" ] | 
|  | } | 
|  |  | 
|  | _final_deps = [] | 
|  |  | 
|  | if (_enable_multidex) { | 
|  | _generated_proguard_main_dex_config = | 
|  | "$_base_path.resources.main-dex-proguard.txt" | 
|  | } | 
|  | _generated_proguard_config = "$_base_path.resources.proguard.txt" | 
|  |  | 
|  | if (_generate_buildconfig_java && | 
|  | defined(invoker.product_version_resources_dep)) { | 
|  | _deps += [ invoker.product_version_resources_dep ] | 
|  | } | 
|  |  | 
|  | _compile_resources_target = "${_template_name}__compile_resources" | 
|  |  | 
|  | if (android_enable_app_bundles) { | 
|  | # Path to the intermediate proto-format resources zip file. | 
|  | _packaged_proto_resources_path = | 
|  | "$root_gen_dir/proto_resources/" + | 
|  | rebase_path(_final_apk_path_no_ext, root_build_dir) + ".proto.ap_" | 
|  |  | 
|  | # Define another target used to generate an archive containing the | 
|  | # resources compiled in protocol buffer format. This is not used by | 
|  | # the APK itself, but by android_bundle_module() targets that depend | 
|  | # on it. | 
|  | _compile_proto_resources_target = | 
|  | "${_template_name}__compile_proto_resources" | 
|  | } | 
|  |  | 
|  | compile_apk_resources(_compile_resources_target) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "alternative_android_sdk_jar", | 
|  | "app_as_shared_lib", | 
|  | "shared_resources", | 
|  | "support_zh_hk", | 
|  | "aapt_locale_whitelist", | 
|  | "exclude_xxxhdpi", | 
|  | "png_to_webp", | 
|  | "xxxhdpi_whitelist", | 
|  | "no_xml_namespaces", | 
|  | ]) | 
|  | android_manifest = _android_manifest | 
|  | version_code = _version_code | 
|  | version_name = _version_name | 
|  |  | 
|  | # Subtle: required to avoid GN build errors. "testonly" cannot be added | 
|  | # to the forward_variables_from() above because it was already forwarded | 
|  | # at the start of android_apk(). And if the assignment below is not | 
|  | # performed, GN will complain that some test-only targets depend | 
|  | # on non-test-only ones. | 
|  | testonly = defined(testonly) && testonly | 
|  |  | 
|  | if (defined(invoker.post_process_package_resources_script)) { | 
|  | post_process_script = invoker.post_process_package_resources_script | 
|  | } | 
|  | srcjar_path = "${target_gen_dir}/${target_name}.srcjar" | 
|  | r_text_out_path = "${target_gen_dir}/${target_name}_R.txt" | 
|  | proguard_file = _generated_proguard_config | 
|  | if (_enable_multidex) { | 
|  | proguard_file_main_dex = _generated_proguard_main_dex_config | 
|  | } | 
|  | output = _packaged_resources_path | 
|  |  | 
|  | build_config = _build_config | 
|  | deps = _deps + [ | 
|  | ":$_merge_manifest_target", | 
|  | ":$_build_config_target", | 
|  | ] | 
|  | if (defined(invoker.shared_resources_whitelist_target)) { | 
|  | _whitelist_gen_dir = | 
|  | get_label_info(invoker.shared_resources_whitelist_target, | 
|  | "target_gen_dir") | 
|  | _whitelist_target_name = | 
|  | get_label_info(invoker.shared_resources_whitelist_target, "name") | 
|  | shared_resources_whitelist = | 
|  | "${_whitelist_gen_dir}/${_whitelist_target_name}" + | 
|  | "__compile_resources_R.txt" | 
|  | deps += [ | 
|  | "${invoker.shared_resources_whitelist_target}__compile_resources", | 
|  | ] | 
|  | } | 
|  |  | 
|  | if (android_enable_app_bundles) { | 
|  | proto_output = _packaged_proto_resources_path | 
|  | proto_resources_target = _compile_proto_resources_target | 
|  | } | 
|  | } | 
|  | _srcjar_deps += [ ":$_compile_resources_target" ] | 
|  |  | 
|  | if (_native_libs_deps != []) { | 
|  | _enable_chromium_linker_tests = false | 
|  | if (defined(invoker.enable_chromium_linker_tests)) { | 
|  | _enable_chromium_linker_tests = invoker.enable_chromium_linker_tests | 
|  | } | 
|  | _ordered_libraries_json = | 
|  | "$target_gen_dir/$target_name.ordered_libararies.json" | 
|  | _rebased_ordered_libraries_json = | 
|  | rebase_path(_ordered_libraries_json, root_build_dir) | 
|  | _ordered_libraries_target = "${_template_name}__write_ordered_libraries" | 
|  |  | 
|  | # TODO(agrieve): Make GN write runtime deps in dependency order so as to | 
|  | # not need this manual sorting step. | 
|  | action(_ordered_libraries_target) { | 
|  | script = "//build/android/gyp/write_ordered_libraries.py" | 
|  | deps = [ | 
|  | ":$_build_config_target", | 
|  | ":${_template_name}__runtime_deps", | 
|  | ] | 
|  | inputs = [ | 
|  | _runtime_deps_file, | 
|  | ] | 
|  | outputs = [ | 
|  | _ordered_libraries_json, | 
|  | ] | 
|  | _rebased_android_readelf = rebase_path(android_readelf, root_build_dir) | 
|  | args = [ | 
|  | "--readelf=$_rebased_android_readelf", | 
|  | "--output=$_rebased_ordered_libraries_json", | 
|  | "--runtime-deps=" + rebase_path(_runtime_deps_file, root_build_dir), | 
|  | ] | 
|  | if (defined(invoker.dont_load_shared_libraries)) { | 
|  | args += [ "--exclude-shared-libraries=" + | 
|  | invoker.dont_load_shared_libraries ] | 
|  | } | 
|  | } | 
|  |  | 
|  | java_cpp_template("${_template_name}__native_libraries_java") { | 
|  | package_path = "org/chromium/base/library_loader" | 
|  | sources = [ | 
|  | "//base/android/java/templates/NativeLibraries.template", | 
|  | ] | 
|  | inputs = [ | 
|  | _ordered_libraries_json, | 
|  | ] | 
|  | deps = [ | 
|  | ":${_ordered_libraries_target}", | 
|  | ] | 
|  | if (_native_lib_version_rule != "") { | 
|  | deps += [ _native_lib_version_rule ] | 
|  | } | 
|  |  | 
|  | defines = [ | 
|  | "NATIVE_LIBRARIES_LIST=" + | 
|  | "@FileArg($_rebased_ordered_libraries_json:java_libraries_list)", | 
|  | "NATIVE_LIBRARIES_VERSION_NUMBER=$_native_lib_version_arg", | 
|  | ] | 
|  | if (current_cpu == "arm" || current_cpu == "arm64") { | 
|  | defines += [ "ANDROID_APP_CPU_FAMILY_ARM" ] | 
|  | } else if (current_cpu == "x86" || current_cpu == "x64") { | 
|  | defines += [ "ANDROID_APP_CPU_FAMILY_X86" ] | 
|  | } else if (current_cpu == "mipsel" || current_cpu == "mips64el") { | 
|  | defines += [ "ANDROID_APP_CPU_FAMILY_MIPS" ] | 
|  | } else { | 
|  | assert(false, "Unsupported CPU family") | 
|  | } | 
|  | if (_use_chromium_linker) { | 
|  | defines += [ "ENABLE_CHROMIUM_LINKER" ] | 
|  | } | 
|  | if (_load_library_from_apk) { | 
|  | defines += [ "ENABLE_CHROMIUM_LINKER_LIBRARY_IN_ZIP_FILE" ] | 
|  | } | 
|  | if (_enable_chromium_linker_tests) { | 
|  | defines += [ "ENABLE_CHROMIUM_LINKER_TESTS" ] | 
|  | } | 
|  | } | 
|  | _srcjar_deps += [ ":${_template_name}__native_libraries_java" ] | 
|  | } | 
|  |  | 
|  | if (_generate_buildconfig_java) { | 
|  | generate_build_config_srcjar("${_template_name}__build_config_java") { | 
|  | forward_variables_from(invoker, [ "firebase_app_id" ]) | 
|  | use_final_fields = true | 
|  | build_config = _build_config | 
|  | enable_multidex = _enable_multidex | 
|  | if (defined(invoker.product_version_resources_dep)) { | 
|  | resources_version_variable = | 
|  | "org.chromium.base.R.string.product_version" | 
|  | } | 
|  | deps = [ | 
|  | ":$_build_config_target", | 
|  | ] | 
|  | } | 
|  | _srcjar_deps += [ ":${_template_name}__build_config_java" ] | 
|  | } | 
|  |  | 
|  | _java_target = "${_template_name}__java" | 
|  | java_library_impl(_java_target) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "android_manifest", | 
|  | "android_manifest_dep", | 
|  | "apk_under_test", | 
|  | "chromium_code", | 
|  | "classpath_deps", | 
|  | "emma_never_instrument", | 
|  | "java_files", | 
|  | "no_build_hooks", | 
|  | "javac_args", | 
|  | ]) | 
|  | type = "android_apk" | 
|  | main_target_name = _template_name | 
|  | supports_android = true | 
|  | requires_android = true | 
|  | deps = _deps | 
|  |  | 
|  | srcjar_deps = _srcjar_deps | 
|  | final_jar_path = _jar_path | 
|  | dex_path = _lib_dex_path | 
|  | apk_path = _final_apk_path | 
|  |  | 
|  | if (android_enable_app_bundles) { | 
|  | proto_resources_path = _packaged_proto_resources_path | 
|  | } | 
|  |  | 
|  | incremental_allowed = _incremental_allowed | 
|  | incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk" | 
|  | incremental_install_json_path = _incremental_install_json_path | 
|  |  | 
|  | proguard_enabled = _proguard_enabled | 
|  | if (_proguard_enabled) { | 
|  | proguard_configs = [ _generated_proguard_config ] | 
|  | if (defined(invoker.proguard_configs)) { | 
|  | proguard_configs += invoker.proguard_configs | 
|  | } | 
|  | if (_enable_multidex) { | 
|  | proguard_configs += [ "//build/android/multidex.flags" ] | 
|  | } | 
|  | } | 
|  | non_native_packed_relocations = _pack_relocations | 
|  |  | 
|  | # Don't depend on the runtime_deps target in order to avoid having to | 
|  | # build the native libraries just to create the .build_config file. | 
|  | # The dep is unnecessary since the runtime_deps file is created by gn gen | 
|  | # and the runtime_deps file is added to write_build_config.py's depfile. | 
|  | if (_native_libs_deps != []) { | 
|  | shared_libraries_runtime_deps_file = _runtime_deps_file | 
|  | } | 
|  | if (_secondary_abi_native_libs_deps != []) { | 
|  | secondary_abi_shared_libraries_runtime_deps_file = | 
|  | _secondary_abi_runtime_deps_file | 
|  | } | 
|  | } | 
|  |  | 
|  | # TODO(cjhopman): This is only ever needed to calculate the list of tests to | 
|  | # run. See build/android/pylib/instrumentation/test_jar.py. We should be | 
|  | # able to just do that calculation at build time instead. | 
|  | if (defined(invoker.dist_ijar_path)) { | 
|  | _dist_ijar_path = invoker.dist_ijar_path | 
|  | dist_jar("${_template_name}_dist_ijar") { | 
|  | override_build_config = _build_config | 
|  | output = _dist_ijar_path | 
|  | data = [ | 
|  | _dist_ijar_path, | 
|  | ] | 
|  | use_interface_jars = true | 
|  | deps = [ | 
|  | ":$_build_config_target", | 
|  | ":$_java_target", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | if (_proguard_enabled) { | 
|  | _proguard_target = "${_template_name}__proguard" | 
|  | proguard(_proguard_target) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "alternative_android_sdk_jar", | 
|  | "proguard_jar_path", | 
|  | ]) | 
|  | deps = _deps + [ | 
|  | ":$_build_config_target", | 
|  | ":$_compile_resources_target", | 
|  | ":$_java_target", | 
|  | ] | 
|  | inputs = [ | 
|  | _build_config, | 
|  | _jar_path, | 
|  | ] | 
|  |  | 
|  | output_jar_path = _proguard_output_jar_path | 
|  | args = [ | 
|  | "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", | 
|  | "--input-paths=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)", | 
|  | "--classpath=@FileArg($_rebased_build_config:deps_info:proguard_all_extra_jars)", | 
|  | ] | 
|  | if (defined(invoker.proguard_config_exclusions)) { | 
|  | _rebased_proguard_config_exclusions = | 
|  | rebase_path(invoker.proguard_config_exclusions, root_build_dir) | 
|  | args += [ | 
|  | "--proguard-config-exclusions=$_rebased_proguard_config_exclusions", | 
|  | ] | 
|  | } | 
|  | } | 
|  | _dex_sources = [ _proguard_output_jar_path ] | 
|  | _dex_deps = [ ":$_proguard_target" ] | 
|  |  | 
|  | _copy_proguard_mapping_target = "${_template_name}__copy_proguard_mapping" | 
|  | copy(_copy_proguard_mapping_target) { | 
|  | sources = [ | 
|  | "$_proguard_output_jar_path.mapping", | 
|  | ] | 
|  | outputs = [ | 
|  | "$_final_apk_path.mapping", | 
|  | ] | 
|  | deps = [ | 
|  | ":$_proguard_target", | 
|  | ] | 
|  | } | 
|  | } else { | 
|  | if (_enable_multidex) { | 
|  | # .jar already included in java_runtime_classpath. | 
|  | _dex_sources = [] | 
|  | } else { | 
|  | _dex_sources = [ _lib_dex_path ] | 
|  | } | 
|  | _dex_deps = [ ":$_java_target" ] | 
|  | } | 
|  |  | 
|  | dex("$_final_dex_target_name") { | 
|  | deps = _dex_deps + [ ":$_build_config_target" ] | 
|  | input_jars = _dex_sources | 
|  | output = _final_dex_path | 
|  | enable_multidex = _enable_multidex | 
|  |  | 
|  | if (_enable_multidex) { | 
|  | forward_variables_from(invoker, [ "negative_main_dex_globs" ]) | 
|  | extra_main_dex_proguard_config = _generated_proguard_main_dex_config | 
|  | deps += [ ":$_compile_resources_target" ] | 
|  | } | 
|  |  | 
|  | # All deps are already included in _dex_sources when proguard is used. | 
|  | if (!_proguard_enabled) { | 
|  | if (_enable_multidex) { | 
|  | _dex_arg_key = | 
|  | "${_rebased_build_config}:deps_info:java_runtime_classpath" | 
|  | } else { | 
|  | _dex_arg_key = | 
|  | "${_rebased_build_config}:final_dex:dependency_dex_files" | 
|  | } | 
|  | build_config = _build_config | 
|  | input_jars_file_arg = "@FileArg($_dex_arg_key)" | 
|  | } | 
|  |  | 
|  | # http://crbug.com/725224. Fix for bots running out of memory. | 
|  | use_pool = true | 
|  | } | 
|  |  | 
|  | _native_libs_file_arg_dep = ":$_build_config_target" | 
|  | _native_libs_file_arg = "@FileArg($_rebased_build_config:native:libraries)" | 
|  | _secondary_abi_native_libs_file_arg_dep = ":$_build_config_target" | 
|  | _secondary_abi_native_libs_file_arg = | 
|  | "@FileArg($_rebased_build_config:native:secondary_abi_libraries)" | 
|  | assert(_secondary_abi_native_libs_file_arg != "" && | 
|  | _secondary_abi_native_libs_file_arg_dep != "")  # Mark as used. | 
|  |  | 
|  | if (_native_libs_deps != [] && _pack_relocations) { | 
|  | _prepare_native_target_name = "${_template_name}__prepare_native" | 
|  | _native_libs_json = "$_gen_dir/packed-libs/filelist.json" | 
|  | _rebased_native_libs_json = rebase_path(_native_libs_json, root_build_dir) | 
|  | _native_libs_file_arg_dep = ":$_prepare_native_target_name" | 
|  | _native_libs_file_arg = "@FileArg($_rebased_native_libs_json:files)" | 
|  |  | 
|  | pack_relocation_section(_prepare_native_target_name) { | 
|  | file_list_json = _native_libs_json | 
|  | libraries_filearg = | 
|  | "@FileArg(${_rebased_build_config}:native:libraries)" | 
|  | inputs = [ | 
|  | _build_config, | 
|  | ] | 
|  |  | 
|  | deps = _native_libs_deps | 
|  | deps += [ ":$_build_config_target" ] | 
|  | } | 
|  | if (_secondary_abi_native_libs_deps != []) { | 
|  | _prepare_native_target_name = | 
|  | "${_template_name}_secondary_abi__prepare_native" | 
|  | _native_libs_json = | 
|  | "$_gen_dir/packed-libs/$android_secondary_abi_cpu/filelist.json" | 
|  | _rebased_native_libs_json = | 
|  | rebase_path(_native_libs_json, root_build_dir) | 
|  | _secondary_abi_native_libs_file_arg_dep = | 
|  | ":$_prepare_native_target_name" | 
|  | _secondary_abi_native_libs_file_arg = | 
|  | "@FileArg($_rebased_native_libs_json:files)" | 
|  |  | 
|  | pack_relocation_section(_prepare_native_target_name) { | 
|  | file_list_json = _native_libs_json | 
|  | libraries_filearg = "@FileArg(${_rebased_build_config}:native:secondary_abi_libraries)" | 
|  | inputs = [ | 
|  | _build_config, | 
|  | ] | 
|  |  | 
|  | deps = _secondary_abi_native_libs_deps | 
|  | deps += [ ":$_build_config_target" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | _extra_native_libs = _sanitizer_runtimes | 
|  | _extra_native_libs_deps = [] | 
|  | assert(_extra_native_libs_deps == [])  # Mark as used. | 
|  | _extra_native_libs_even_when_incremental = [] | 
|  | if (_native_libs_deps != []) { | 
|  | if (_use_chromium_linker) { | 
|  | _extra_native_libs += | 
|  | [ "$root_shlib_dir/libchromium_android_linker$shlib_extension" ] | 
|  | _extra_native_libs_deps += | 
|  | [ "//base/android/linker:chromium_android_linker" ] | 
|  | } | 
|  |  | 
|  | _create_stack_script_rule_name = "${_template_name}__stack_script" | 
|  | _final_deps += [ ":${_create_stack_script_rule_name}" ] | 
|  | stack_script(_create_stack_script_rule_name) { | 
|  | stack_target_name = invoker.target_name | 
|  | deps = _native_libs_deps | 
|  | if (_native_libs_deps != [] && _pack_relocations) { | 
|  | packed_libraries = _native_libs_file_arg | 
|  | deps += [ _native_libs_file_arg_dep ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (defined(invoker.loadable_modules) && invoker.loadable_modules != []) { | 
|  | _extra_native_libs_even_when_incremental += invoker.loadable_modules | 
|  | } | 
|  |  | 
|  | # Generate .apk.jar.info files if needed. | 
|  | if (defined(invoker.apk_name)) { | 
|  | _apk_jar_info_target = "${target_name}__apk_jar_info" | 
|  | create_apk_jar_info(_apk_jar_info_target) { | 
|  | output = "$root_build_dir/size-info/${invoker.apk_name}.apk.jar.info" | 
|  | apk_build_config = _build_config | 
|  | deps = [ | 
|  | ":$_build_config_target", | 
|  | ":$_java_target", | 
|  | ] | 
|  | } | 
|  | _deps += [ ":$_apk_jar_info_target" ] | 
|  | } | 
|  |  | 
|  | _final_deps += [ ":${_template_name}__create" ] | 
|  | create_apk("${_template_name}__create") { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "alternative_android_sdk_jar", | 
|  | "public_deps", | 
|  | "secondary_native_libs", | 
|  | "shared_resources", | 
|  | "uncompress_shared_libraries", | 
|  | "write_asset_list", | 
|  | ]) | 
|  | packaged_resources_path = _packaged_resources_path | 
|  | apk_path = _final_apk_path | 
|  | android_manifest = _android_manifest | 
|  | assets_build_config = _build_config | 
|  | base_path = _base_path | 
|  | dex_path = _final_dex_path | 
|  | load_library_from_apk = _load_library_from_apk | 
|  |  | 
|  | # This is used to generate *.apk.pak.info files. | 
|  | apk_name = invoker.apk_name | 
|  |  | 
|  | keystore_name = _keystore_name | 
|  | keystore_path = _keystore_path | 
|  | keystore_password = _keystore_password | 
|  |  | 
|  | # Incremental apk does not use native libs nor final dex. | 
|  | incremental_deps = _deps + [ | 
|  | ":$_merge_manifest_target", | 
|  | ":$_build_config_target", | 
|  | ":$_compile_resources_target", | 
|  | ] | 
|  |  | 
|  | # This target generates the input file _all_resources_zip_path. | 
|  | deps = _deps + [ | 
|  | ":$_merge_manifest_target", | 
|  | ":$_build_config_target", | 
|  | ":$_final_dex_target_name", | 
|  | ":$_compile_resources_target", | 
|  | ] | 
|  |  | 
|  | if (_native_libs_deps != [] || | 
|  | _extra_native_libs_even_when_incremental != []) { | 
|  | deps += _native_libs_deps + _extra_native_libs_deps + | 
|  | [ _native_libs_file_arg_dep ] | 
|  | native_libs_filearg = _native_libs_file_arg | 
|  | native_libs = _extra_native_libs | 
|  | native_libs_even_when_incremental = | 
|  | _extra_native_libs_even_when_incremental | 
|  | } | 
|  |  | 
|  | if (_secondary_abi_native_libs_deps != []) { | 
|  | deps += _secondary_abi_native_libs_deps + | 
|  | [ _secondary_abi_native_libs_file_arg_dep ] | 
|  | secondary_abi_native_libs_filearg = _secondary_abi_native_libs_file_arg | 
|  | } | 
|  |  | 
|  | # Placeholders necessary for some older devices. | 
|  | # http://crbug.com/395038 | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "native_lib_placeholders", | 
|  | "secondary_native_lib_placeholders", | 
|  | ]) | 
|  | } | 
|  |  | 
|  | _write_installer_json_rule_name = "${_template_name}__incremental_json" | 
|  | action(_write_installer_json_rule_name) { | 
|  | script = "//build/android/incremental_install/write_installer_json.py" | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  | deps = [ | 
|  | _native_libs_file_arg_dep, | 
|  | ] | 
|  |  | 
|  | outputs = [ | 
|  | _incremental_install_json_path, | 
|  | ] | 
|  |  | 
|  | _rebased_apk_path_no_ext = | 
|  | rebase_path(_final_apk_path_no_ext, root_build_dir) | 
|  | _rebased_incremental_install_json_path = | 
|  | rebase_path(_incremental_install_json_path, root_build_dir) | 
|  | _rebased_depfile = rebase_path(depfile, root_build_dir) | 
|  | _dex_arg_key = "${_rebased_build_config}:final_dex:dependency_dex_files" | 
|  | args = [ | 
|  | "--apk-path=${_rebased_apk_path_no_ext}_incremental.apk", | 
|  | "--output-path=$_rebased_incremental_install_json_path", | 
|  | "--dex-file=$_rebased_lib_dex_path", | 
|  | "--dex-file-list=@FileArg($_dex_arg_key)", | 
|  | "--depfile=$_rebased_depfile", | 
|  | ] | 
|  | if (_proguard_enabled) { | 
|  | args += [ "--show-proguard-warning" ] | 
|  | } | 
|  | if (defined(_native_libs_file_arg)) { | 
|  | args += [ "--native-libs=$_native_libs_file_arg" ] | 
|  | } | 
|  | if (_extra_native_libs != []) { | 
|  | # Don't pass in _extra_native_libs_even_when_incremental, since these are | 
|  | # end up in the apk and are not side-loaded. | 
|  | _rebased_extra_native_libs = | 
|  | rebase_path(_extra_native_libs, root_build_dir) | 
|  | args += [ "--native-libs=$_rebased_extra_native_libs" ] | 
|  | } | 
|  | if (_load_library_from_apk) { | 
|  | args += [ "--dont-even-try=Incremental builds do not work with load_library_from_apk. Try setting is_component_build=true in your GN args." ] | 
|  | } | 
|  | } | 
|  |  | 
|  | _apk_operations = [] | 
|  | _incremental_apk_operations = [] | 
|  |  | 
|  | # Generate apk operation related script. | 
|  | if (!defined(invoker.create_apk_script) || invoker.create_apk_script) { | 
|  | _apk_operations_target_name = "${target_name}__apk_operations" | 
|  | action(_apk_operations_target_name) { | 
|  | _generated_script = "$root_build_dir/bin/${invoker.target_name}" | 
|  | script = "//build/android/gyp/create_apk_operations_script.py" | 
|  | outputs = [ | 
|  | _generated_script, | 
|  | ] | 
|  | if (_proguard_enabled) { | 
|  | # Required by logcat command. | 
|  | data_deps = [ | 
|  | "//build/android/stacktrace:java_deobfuscate", | 
|  | ] | 
|  | } | 
|  | args = [ | 
|  | "--script-output-path", | 
|  | rebase_path(_generated_script, root_build_dir), | 
|  | "--apk-path", | 
|  | rebase_path(_final_apk_path, root_build_dir), | 
|  | "--target-cpu=$target_cpu", | 
|  | ] | 
|  | if (defined(invoker.command_line_flags_file)) { | 
|  | args += [ | 
|  | "--command-line-flags-file", | 
|  | invoker.command_line_flags_file, | 
|  | ] | 
|  | } | 
|  | if (_incremental_allowed) { | 
|  | args += [ | 
|  | "--incremental-install-json-path", | 
|  | rebase_path(_incremental_install_json_path, root_build_dir), | 
|  | ] | 
|  | } | 
|  | if (_proguard_enabled) { | 
|  | args += [ | 
|  | "--proguard-mapping-path", | 
|  | rebase_path("$_final_apk_path.mapping", root_build_dir), | 
|  | ] | 
|  | } | 
|  | } | 
|  | _apk_operations += [ ":$_apk_operations_target_name" ] | 
|  | _incremental_apk_operations += [ ":$_apk_operations_target_name" ] | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | if (_incremental_allowed && incremental_apk_by_default) { | 
|  | deps = [ | 
|  | ":${target_name}_incremental", | 
|  | ] | 
|  | assert(_apk_operations != [] || true)  # Prevent "unused variable". | 
|  | } else { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "data", | 
|  | "data_deps", | 
|  | ]) | 
|  | public_deps = _final_deps | 
|  |  | 
|  | # Generate apk related operations at runtime. | 
|  | public_deps += _apk_operations | 
|  |  | 
|  | # Make the proguard .mapping file easy to find by putting it beside the .apk. | 
|  | if (_proguard_enabled) { | 
|  | deps = [ | 
|  | ":$_copy_proguard_mapping_target", | 
|  | ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (_incremental_allowed) { | 
|  | group("${target_name}_incremental") { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "data", | 
|  | "data_deps", | 
|  | ]) | 
|  | if (!defined(data_deps)) { | 
|  | data_deps = [] | 
|  | } | 
|  |  | 
|  | # device/commands is used by the installer script to push files via .zip. | 
|  | data_deps += [ "//build/android/pylib/device/commands" ] + | 
|  | _native_libs_deps + _extra_native_libs_deps | 
|  |  | 
|  | # Since the _incremental.apk does not include use .so nor .dex from the | 
|  | # actual target, but instead loads them at runtime, we need to explicitly | 
|  | # depend on them here. | 
|  | public_deps = [ | 
|  | ":${_java_target}", | 
|  | ":${_template_name}__create_incremental", | 
|  | ":${_write_installer_json_rule_name}", | 
|  | ] | 
|  |  | 
|  | # Generate incremental apk related operations at runtime. | 
|  | public_deps += _incremental_apk_operations | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android instrumentation test apk | 
|  | # | 
|  | # This target creates an Android instrumentation test apk. | 
|  | # | 
|  | # Variables | 
|  | #   android_manifest: Path to AndroidManifest.xml. | 
|  | #   data_deps: List of dependencies needed at runtime. These will be built but | 
|  | #     won't change the generated .apk in any way (in fact they may be built | 
|  | #     after the .apk is). | 
|  | #   deps: List of dependencies. All Android java resources and libraries in the | 
|  | #     "transitive closure" of these dependencies will be included in the apk. | 
|  | #     Note: this "transitive closure" actually only includes such targets if | 
|  | #     they are depended on through android_library or android_resources targets | 
|  | #     (and so not through builtin targets like 'action', 'group', etc). | 
|  | #   java_files: List of .java files to include in the apk. | 
|  | #   srcjar_deps: List of srcjar dependencies. The .java files in the srcjars | 
|  | #      will be added to java_files and be included in this apk. | 
|  | #   apk_name: Name for final apk. | 
|  | #   final_apk_path: Path to final built apk. Default is | 
|  | #     $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name. | 
|  | #   shared_libraries: List shared_library targets to bundle. If these | 
|  | #     libraries depend on other shared_library targets, those dependencies will | 
|  | #     also be included in the apk (e.g. for is_component_build). | 
|  | #   apk_under_test: The apk being tested. | 
|  | #   javac_args: Additional arguments to pass to javac. | 
|  | # | 
|  | # Example | 
|  | #   instrumentation_test_apk("foo_test_apk") { | 
|  | #     android_manifest = "AndroidManifest.xml" | 
|  | #     apk_name = "FooTest" | 
|  | #     apk_under_test = "Foo" | 
|  | #     java_files = [ | 
|  | #       "android/org/chromium/foo/FooTestCase.java", | 
|  | #       "android/org/chromium/foo/FooExampleTest.java", | 
|  | #     ] | 
|  | #     deps = [ | 
|  | #       ":foo_test_support_java" | 
|  | #     ] | 
|  | #   } | 
|  | template("instrumentation_test_apk") { | 
|  | assert(defined(invoker.apk_name)) | 
|  | testonly = true | 
|  | _apk_target_name = "${target_name}__apk" | 
|  | _test_runner_target_name = "${target_name}__test_runner_script" | 
|  | _dist_ijar_path = | 
|  | "$root_build_dir/test.lib.java/" + invoker.apk_name + ".jar" | 
|  | _incremental_test_runner_target_name = | 
|  | "${_test_runner_target_name}_incremental" | 
|  | _incremental_test_name = "${invoker.target_name}_incremental" | 
|  | if (incremental_apk_by_default) { | 
|  | _incremental_test_runner_target_name = _test_runner_target_name | 
|  | _incremental_test_name = invoker.target_name | 
|  | } | 
|  |  | 
|  | if (!incremental_apk_by_default) { | 
|  | test_runner_script(_test_runner_target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "additional_apks", | 
|  | "apk_under_test", | 
|  | "data", | 
|  | "data_deps", | 
|  | "deps", | 
|  | "ignore_all_data_deps", | 
|  | "proguard_enabled", | 
|  | "public_deps", | 
|  | ]) | 
|  | test_name = invoker.target_name | 
|  | test_type = "instrumentation" | 
|  | apk_target = ":$_apk_target_name" | 
|  | test_jar = _dist_ijar_path | 
|  | } | 
|  | } | 
|  | test_runner_script(_incremental_test_runner_target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "additional_apks", | 
|  | "apk_under_test", | 
|  | "data", | 
|  | "data_deps", | 
|  | "deps", | 
|  | "ignore_all_data_deps", | 
|  | "public_deps", | 
|  | ]) | 
|  | test_name = _incremental_test_name | 
|  | test_type = "instrumentation" | 
|  | apk_target = ":$_apk_target_name" | 
|  | test_jar = _dist_ijar_path | 
|  | incremental_install = true | 
|  | } | 
|  |  | 
|  | android_apk(_apk_target_name) { | 
|  | deps = [] | 
|  | data_deps = [] | 
|  | forward_variables_from(invoker, "*") | 
|  | deps += [ "//testing/android/broker:broker_java" ] | 
|  | data_deps += [ | 
|  | "//build/android/pylib/device/commands", | 
|  | "//tools/android/forwarder2", | 
|  | "//tools/android/md5sum", | 
|  | ] | 
|  | if (defined(invoker.apk_under_test)) { | 
|  | data_deps += [ invoker.apk_under_test ] | 
|  | } | 
|  | if (defined(invoker.additional_apks)) { | 
|  | data_deps += invoker.additional_apks | 
|  | } | 
|  | if (defined(invoker.apk_under_test)) { | 
|  | # Prevent a build_hooks_android_impl exising in both the test apks as | 
|  | # well as the apk_under_test. | 
|  | no_build_hooks = true | 
|  | } | 
|  |  | 
|  | if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { | 
|  | # When ProGuard is on, we use ProGuard to combine the under test java | 
|  | # code and the test java code. This is to allow us to apply all ProGuard | 
|  | # optimizations that we ship with, but not have them break tests. The | 
|  | # apk under test will still have the same resources, assets, and | 
|  | # manifest, all of which are the ones used in the tests. | 
|  | if (!defined(invoker.proguard_configs)) { | 
|  | proguard_configs = [] | 
|  | } | 
|  | proguard_configs += [ "//testing/android/proguard_for_test.flags" ] | 
|  | if (defined(final_apk_path)) { | 
|  | _final_apk_path = final_apk_path | 
|  | } else { | 
|  | _final_apk_path = "$root_build_dir/apks/${apk_name}.apk" | 
|  | } | 
|  | data = [ | 
|  | "$_final_apk_path.mapping", | 
|  | ] | 
|  | } | 
|  |  | 
|  | dist_ijar_path = _dist_ijar_path | 
|  | create_apk_script = false | 
|  | } | 
|  |  | 
|  | group(target_name) { | 
|  | if (incremental_apk_by_default) { | 
|  | public_deps = [ | 
|  | ":${target_name}_incremental", | 
|  | ] | 
|  | } else { | 
|  | public_deps = [ | 
|  | ":$_apk_target_name", | 
|  | ":$_test_runner_target_name", | 
|  |  | 
|  | # Required by test runner to enumerate test list. | 
|  | ":${_apk_target_name}_dist_ijar", | 
|  | ] | 
|  | if (defined(invoker.apk_under_test)) { | 
|  | public_deps += [ invoker.apk_under_test ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Ensure unstripped libraries are included in runtime deps so that | 
|  | # symbolization can be done. | 
|  | deps = [ | 
|  | ":${_apk_target_name}__runtime_deps", | 
|  | ":${_apk_target_name}__secondary_abi_runtime_deps", | 
|  | ] | 
|  | if (defined(invoker.apk_under_test)) { | 
|  | _under_test_label = | 
|  | get_label_info(invoker.apk_under_test, "label_no_toolchain") | 
|  | deps += [ | 
|  | "${_under_test_label}__runtime_deps", | 
|  | "${_under_test_label}__secondary_abi_runtime_deps", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | group("${target_name}_incremental") { | 
|  | public_deps = [ | 
|  | ":$_incremental_test_runner_target_name", | 
|  | ":${_apk_target_name}_dist_ijar", | 
|  | ":${_apk_target_name}_incremental", | 
|  | ] | 
|  | if (defined(invoker.apk_under_test)) { | 
|  | public_deps += [ "${invoker.apk_under_test}_incremental" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android gtest apk | 
|  | # | 
|  | # This target creates an Android apk for running gtest-based unittests. | 
|  | # | 
|  | # Variables | 
|  | #   deps: Specifies the dependencies of this target. These will be passed to | 
|  | #     the underlying android_apk invocation and should include the java and | 
|  | #     resource dependencies of the apk. | 
|  | #   shared_library: shared_library target that contains the unit tests. | 
|  | #   apk_name: The name of the produced apk. If unspecified, it uses the name | 
|  | #             of the shared_library target suffixed with "_apk" | 
|  | #   use_default_launcher: Whether the default activity (NativeUnitTestActivity) | 
|  | #     should be used for launching tests. | 
|  | #   use_native_activity: Test implements ANativeActivity_onCreate(). | 
|  | # | 
|  | # Example | 
|  | #   unittest_apk("foo_unittests_apk") { | 
|  | #     deps = [ ":foo_java", ":foo_resources" ] | 
|  | #     shared_library = ":foo_unittests" | 
|  | #   } | 
|  | template("unittest_apk") { | 
|  | _use_native_activity = | 
|  | defined(invoker.use_native_activity) && invoker.use_native_activity | 
|  | _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml" | 
|  | assert(invoker.shared_library != "") | 
|  |  | 
|  | # This trivial assert is needed in case android_manifest is defined, | 
|  | # as otherwise _use_native_activity and _android_manifest would not be used. | 
|  | assert(_use_native_activity != "" && _android_manifest != "") | 
|  |  | 
|  | if (!defined(invoker.android_manifest)) { | 
|  | jinja_template("${target_name}_manifest") { | 
|  | _native_library_name = get_label_info(invoker.shared_library, "name") | 
|  | input = "//testing/android/native_test/java/AndroidManifest.xml.jinja2" | 
|  | output = _android_manifest | 
|  | variables = [ | 
|  | "is_component_build=${is_component_build}", | 
|  | "native_library_name=${_native_library_name}", | 
|  | "use_native_activity=${_use_native_activity}", | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | android_apk(target_name) { | 
|  | data_deps = [] | 
|  | forward_variables_from(invoker, "*") | 
|  | testonly = true | 
|  | create_apk_script = false | 
|  |  | 
|  | assert(!defined(invoker.proguard_enabled) || !invoker.proguard_enabled || | 
|  | invoker.proguard_configs != []) | 
|  |  | 
|  | if (!defined(apk_name)) { | 
|  | apk_name = get_label_info(invoker.shared_library, "name") | 
|  | } | 
|  |  | 
|  | if (!defined(android_manifest)) { | 
|  | android_manifest_dep = ":${target_name}_manifest" | 
|  | android_manifest = _android_manifest | 
|  | } | 
|  |  | 
|  | final_apk_path = "$root_build_dir/${apk_name}_apk/${apk_name}-debug.apk" | 
|  |  | 
|  | if (!defined(use_default_launcher) || use_default_launcher) { | 
|  | deps += [ "//testing/android/native_test:native_test_java" ] | 
|  | } | 
|  | shared_libraries = [ invoker.shared_library ] | 
|  | deps += [ | 
|  | ":${target_name}__runtime_deps", | 
|  | ":${target_name}__secondary_abi_runtime_deps", | 
|  | "//base:base_java", | 
|  | "//testing/android/reporter:reporter_java", | 
|  | ] | 
|  | data_deps += [ | 
|  | "//build/android/pylib/device/commands", | 
|  | "//tools/android/md5sum", | 
|  | ] | 
|  | if (host_os == "linux") { | 
|  | data_deps += [ "//tools/android/forwarder2" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Generate .java files from .aidl files. | 
|  | # | 
|  | # This target will store the .java files in a srcjar and should be included in | 
|  | # an android_library or android_apk's srcjar_deps. | 
|  | # | 
|  | # Variables | 
|  | #   sources: Paths to .aidl files to compile. | 
|  | #   import_include: Path to directory containing .java files imported by the | 
|  | #     .aidl files. | 
|  | #   interface_file: Preprocessed aidl file to import. | 
|  | # | 
|  | # Example | 
|  | #   android_aidl("foo_aidl") { | 
|  | #     import_include = "java/src" | 
|  | #     sources = [ | 
|  | #       "java/src/com/foo/bar/FooBarService.aidl", | 
|  | #       "java/src/com/foo/bar/FooBarServiceCallback.aidl", | 
|  | #     ] | 
|  | #   } | 
|  | template("android_aidl") { | 
|  | action(target_name) { | 
|  | set_sources_assignment_filter([]) | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | script = "//build/android/gyp/aidl.py" | 
|  | sources = invoker.sources | 
|  |  | 
|  | _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" | 
|  | _aidl_path = "${android_sdk_build_tools}/aidl" | 
|  | _framework_aidl = "$android_sdk/framework.aidl" | 
|  | _imports = [ _framework_aidl ] | 
|  | if (defined(invoker.interface_file)) { | 
|  | assert(invoker.interface_file != "") | 
|  | _imports += [ invoker.interface_file ] | 
|  | } | 
|  |  | 
|  | inputs = [ _aidl_path ] + _imports | 
|  |  | 
|  | depfile = "${target_gen_dir}/${target_name}.d" | 
|  | outputs = [ | 
|  | _srcjar_path, | 
|  | ] | 
|  | _rebased_imports = rebase_path(_imports, root_build_dir) | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--aidl-path", | 
|  | rebase_path(_aidl_path, root_build_dir), | 
|  | "--imports=$_rebased_imports", | 
|  | "--srcjar", | 
|  | rebase_path(_srcjar_path, root_build_dir), | 
|  | ] | 
|  | if (defined(invoker.import_include) && invoker.import_include != []) { | 
|  | # TODO(cjhopman): aidl supports creating a depfile. We should be able to | 
|  | # switch to constructing a depfile for the overall action from that | 
|  | # instead of having all the .java files in the include paths as inputs. | 
|  | _rebased_import_paths = [] | 
|  | foreach(_import_path, invoker.import_include) { | 
|  | _rebased_import_path = [] | 
|  | _rebased_import_path = [ rebase_path(_import_path, root_build_dir) ] | 
|  | _rebased_import_paths += _rebased_import_path | 
|  | _java_files_build_rel = [] | 
|  | _java_files_build_rel = | 
|  | exec_script("//build/android/gyp/find.py", | 
|  | [ "--pattern=*.java" ] + _rebased_import_path, | 
|  | "list lines") | 
|  | inputs += rebase_path(_java_files_build_rel, ".", root_build_dir) | 
|  | } | 
|  | args += [ "--includes=$_rebased_import_paths" ] | 
|  | } | 
|  | args += rebase_path(sources, root_build_dir) | 
|  | } | 
|  | } | 
|  |  | 
|  | # Compile a protocol buffer to java. | 
|  | # | 
|  | # This generates java files from protocol buffers and creates an Android library | 
|  | # containing the classes. | 
|  | # | 
|  | # Variables | 
|  | #   sources (required) | 
|  | #       Paths to .proto files to compile. | 
|  | # | 
|  | #   proto_path (required) | 
|  | #       Root directory of .proto files. | 
|  | # | 
|  | #   generate_nano (optional, default false) | 
|  | #       Whether to generate nano protos. If false, this will use the lite proto generator. | 
|  | #       Nano protos are deprecated, so please use lite new proto libraries. | 
|  | # | 
|  | # Example: | 
|  | #  proto_java_library("foo_proto_java") { | 
|  | #    proto_path = "src/foo" | 
|  | #    sources = [ "$proto_path/foo.proto" ] | 
|  | #  } | 
|  | template("proto_java_library") { | 
|  | set_sources_assignment_filter([]) | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  | _generate_nano = | 
|  | defined(invoker.generate_nano) && invoker.generate_nano == true | 
|  |  | 
|  | if (_generate_nano) { | 
|  | # Use the legacy Android nano proto generator. | 
|  | _protoc_dep = | 
|  | "//third_party/android_protobuf:android_protoc($host_toolchain)" | 
|  | _protoc_out_dir = get_label_info(_protoc_dep, "root_out_dir") | 
|  | _protoc_bin = "$_protoc_out_dir/android_protoc" | 
|  | _proto_runtime = "//third_party/android_protobuf:protobuf_nano_javalib" | 
|  | } else { | 
|  | # Use the regular proto library to generate lite protos. | 
|  | _protoc_dep = "//third_party/protobuf:protoc($host_toolchain)" | 
|  | _protoc_out_dir = get_label_info(_protoc_dep, "root_out_dir") | 
|  | _protoc_bin = "$_protoc_out_dir/protoc" | 
|  | _proto_runtime = "//third_party/protobuf:protobuf_lite_javalib" | 
|  | } | 
|  | _proto_path = invoker.proto_path | 
|  | _template_name = target_name | 
|  |  | 
|  | action("${_template_name}__protoc_java") { | 
|  | _srcjar_path = "$target_gen_dir/$target_name.srcjar" | 
|  | script = "//build/protoc_java.py" | 
|  |  | 
|  | deps = [ | 
|  | _protoc_dep, | 
|  | ] | 
|  | if (defined(invoker.deps)) { | 
|  | deps += invoker.deps | 
|  | } | 
|  |  | 
|  | sources = invoker.sources | 
|  | depfile = "$target_gen_dir/$target_name.d" | 
|  | outputs = [ | 
|  | _srcjar_path, | 
|  | ] | 
|  | args = [ | 
|  | "--depfile", | 
|  | rebase_path(depfile, root_build_dir), | 
|  | "--protoc", | 
|  | rebase_path(_protoc_bin, root_build_dir), | 
|  | "--proto-path", | 
|  | rebase_path(_proto_path, root_build_dir), | 
|  | "--srcjar", | 
|  | rebase_path(_srcjar_path, root_build_dir), | 
|  | ] + rebase_path(sources, root_build_dir) | 
|  | if (_generate_nano) { | 
|  | args += [ "--nano" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | android_library(target_name) { | 
|  | chromium_code = false | 
|  | java_files = [] | 
|  | srcjar_deps = [ ":${_template_name}__protoc_java" ] | 
|  | deps = [ | 
|  | _proto_runtime, | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Declare an Android library target for a prebuilt AAR. | 
|  | # | 
|  | # This target creates an Android library containing java code and Android | 
|  | # resources. For libraries without resources, it will not generate | 
|  | # corresponding android_resources targets. | 
|  | # | 
|  | # To avoid slowing down "gn gen", an associated .info file must be committed | 
|  | # along with the .aar file. In order to create this file, define the target | 
|  | # and then run once with the gn arg "update_android_aar_prebuilts = true". | 
|  | # | 
|  | # Variables | 
|  | #   aar_path: Path to the AAR. | 
|  | #   info_path: Path to the .aar.info file (generated via | 
|  | #       update_android_aar_prebuilts GN arg). | 
|  | #   proguard_configs: List of proguard configs to use in final apk step for | 
|  | #       any apk that depends on this library. | 
|  | #   ignore_aidl: Whether to ignore .aidl files found with the .aar. | 
|  | #   ignore_assets: Whether to ignore assets found in the .aar. | 
|  | #   ignore_native_libraries: Whether to ignore .so files found in the .aar. | 
|  | #   create_srcjar: If false, does not create an R.java file. | 
|  | #   TODO(jbudorick@): remove this arguments after crbug.com/522043 is fixed. | 
|  | #   requires_android: Whether this target can only be used for compiling | 
|  | #       Android related targets. | 
|  | # | 
|  | # Example | 
|  | #   android_aar_prebuilt("foo_java") { | 
|  | #     aar_path = "foo.aar" | 
|  | #   } | 
|  | template("android_aar_prebuilt") { | 
|  | _info_path = "$target_name.info" | 
|  | if (defined(invoker.info_path)) { | 
|  | _info_path = invoker.info_path | 
|  | } | 
|  | _output_path = "${target_gen_dir}/${target_name}" | 
|  | _unpack_target_name = "${target_name}__unpack_aar" | 
|  | _ignore_aidl = defined(invoker.ignore_aidl) && invoker.ignore_aidl | 
|  | _ignore_assets = defined(invoker.ignore_assets) && invoker.ignore_assets | 
|  | _ignore_native_libraries = defined(invoker.ignore_native_libraries) && | 
|  | invoker.ignore_native_libraries | 
|  |  | 
|  | # Scan the AAR file and determine the resources and jar files. | 
|  | # Some libraries might not have resources; others might have two jars. | 
|  | if (update_android_aar_prebuilts) { | 
|  | print("Writing " + rebase_path(_info_path, "//")) | 
|  | exec_script("//build/android/gyp/aar.py", | 
|  | [ | 
|  | "list", | 
|  | rebase_path(invoker.aar_path, root_build_dir), | 
|  | "--output", | 
|  | rebase_path(_info_path, root_build_dir), | 
|  | ]) | 
|  | } | 
|  |  | 
|  | # If "gn gen" is failing on the following line, you need to generate an | 
|  | # .info file for your new target by running: | 
|  | #   gn gen --args='target_os="android" update_android_aar_prebuilts=true' out/tmp | 
|  | #   rm -r out/tmp | 
|  | _scanned_files = read_file(_info_path, "scope") | 
|  |  | 
|  | assert(_ignore_aidl || _scanned_files.aidl == [], | 
|  | "android_aar_prebuilt() aidl not yet supported." + | 
|  | " Implement or use ignore_aidl = true." + | 
|  | " http://crbug.com/644439") | 
|  | assert(_ignore_assets || _scanned_files.assets == [], | 
|  | "android_aar_prebuilt() assets not yet supported." + | 
|  | " Implement or use ignore_assets = true." + | 
|  | " http://crbug.com/643966") | 
|  | assert(_ignore_native_libraries || !_scanned_files.has_native_libraries, | 
|  | "android_aar_prebuilt() with .so files is not supported." + | 
|  | " Use ignore_native_libraries = true to silence this error.") | 
|  | assert(_scanned_files.has_classes_jar || _scanned_files.subjars == []) | 
|  |  | 
|  | action(_unpack_target_name) { | 
|  | script = "//build/android/gyp/aar.py"  # Unzips the AAR | 
|  | args = [ | 
|  | "extract", | 
|  | rebase_path(invoker.aar_path, root_build_dir), | 
|  | "--output-dir", | 
|  | rebase_path(_output_path, root_build_dir), | 
|  | "--assert-info-file", | 
|  | rebase_path(_info_path, root_build_dir), | 
|  | ] | 
|  | inputs = [ | 
|  | invoker.aar_path, | 
|  | ] | 
|  | outputs = [ | 
|  | "${_output_path}/AndroidManifest.xml", | 
|  | ] | 
|  |  | 
|  | if (_scanned_files.has_r_text_file) { | 
|  | # Certain packages, in particular Play Services have no R.txt even | 
|  | # though its presence is mandated by AAR spec. Such packages cause | 
|  | # spurious rebuilds if this output is specified unconditionally. | 
|  | outputs += [ "${_output_path}/R.txt" ] | 
|  | } | 
|  |  | 
|  | if (_scanned_files.resources != []) { | 
|  | outputs += get_path_info( | 
|  | rebase_path(_scanned_files.resources, "", _output_path), | 
|  | "abspath") | 
|  | } | 
|  | if (_scanned_files.has_classes_jar) { | 
|  | outputs += [ "${_output_path}/classes.jar" ] | 
|  | } | 
|  | outputs += | 
|  | get_path_info(rebase_path(_scanned_files.subjars, "", _output_path), | 
|  | "abspath") | 
|  | if (_scanned_files.has_proguard_flags) { | 
|  | outputs += [ "${_output_path}/proguard.txt" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | # Create the android_resources target for resources. | 
|  | if (_scanned_files.resources != [] || _scanned_files.has_r_text_file || | 
|  | !_scanned_files.is_manifest_empty) { | 
|  | _res_target_name = "${target_name}__res" | 
|  | android_resources(_res_target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "create_srcjar", | 
|  | "deps", | 
|  | "testonly", | 
|  | ]) | 
|  | if (!defined(deps)) { | 
|  | deps = [] | 
|  | } | 
|  | deps += [ ":$_unpack_target_name" ] | 
|  | resource_dirs = [] | 
|  | generated_resource_dirs = [] | 
|  | if (_scanned_files.resources != []) { | 
|  | generated_resource_dirs += [ "${_output_path}/res" ] | 
|  | } | 
|  | generated_resource_files = | 
|  | rebase_path(_scanned_files.resources, "", _output_path) | 
|  | android_manifest_dep = ":$_unpack_target_name" | 
|  | android_manifest = "${_output_path}/AndroidManifest.xml" | 
|  | if (_scanned_files.has_r_text_file) { | 
|  | r_text_file = "${_output_path}/R.txt" | 
|  | } | 
|  | v14_skip = true | 
|  | } | 
|  | } | 
|  |  | 
|  | # Create android_java_prebuilt target for extra jars within jars/. | 
|  | _subjar_targets = [] | 
|  | foreach(_tuple, _scanned_files.subjar_tuples) { | 
|  | _current_target = "${target_name}__subjar_${_tuple[0]}" | 
|  | _subjar_targets += [ ":$_current_target" ] | 
|  | java_prebuilt(_current_target) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "jar_excluded_patterns", | 
|  | "jar_included_patterns", | 
|  | "requires_android", | 
|  | ]) | 
|  | deps = [ | 
|  | ":$_unpack_target_name", | 
|  | ] | 
|  | if (!defined(requires_android)) { | 
|  | requires_android = true | 
|  | } | 
|  | supports_android = true | 
|  | jar_path = "$_output_path/${_tuple[1]}" | 
|  | _base_output_name = get_path_info(jar_path, "name") | 
|  | output_name = "${invoker.target_name}-$_base_output_name" | 
|  | } | 
|  | } | 
|  |  | 
|  | # Create android_java_prebuilt target for classes.jar. | 
|  | if (_scanned_files.has_classes_jar) { | 
|  | _jar_target_name = "${target_name}__classes" | 
|  | java_prebuilt(_jar_target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "input_jars_paths", | 
|  | "jar_excluded_patterns", | 
|  | "jar_included_patterns", | 
|  | "proguard_configs", | 
|  | "requires_android", | 
|  | "testonly", | 
|  | ]) | 
|  | if (!defined(deps)) { | 
|  | deps = [] | 
|  | } | 
|  | deps += _subjar_targets + [ ":$_unpack_target_name" ] | 
|  | if (defined(_res_target_name)) { | 
|  | deps += [ ":$_res_target_name" ] | 
|  | } | 
|  | if (!defined(requires_android)) { | 
|  | requires_android = true | 
|  | } | 
|  | supports_android = true | 
|  | jar_path = "$_output_path/classes.jar" | 
|  | output_name = invoker.target_name | 
|  |  | 
|  | if (_scanned_files.has_proguard_flags) { | 
|  | if (!defined(proguard_configs)) { | 
|  | proguard_configs = [] | 
|  | } | 
|  | proguard_configs += [ "$_output_path/proguard.txt" ] | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | java_group(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "testonly", | 
|  | "visibility", | 
|  | ]) | 
|  | public_deps = [ | 
|  | ":$_unpack_target_name", | 
|  | ] | 
|  | deps = [] | 
|  | if (defined(_jar_target_name)) { | 
|  | deps += [ ":$_jar_target_name" ] | 
|  |  | 
|  | # Although subjars are meant to be private, we add them as deps here | 
|  | # because in practice they seem to contain classes required to be in the | 
|  | # classpath. | 
|  | deps += _subjar_targets | 
|  | } | 
|  | if (defined(_res_target_name)) { | 
|  | deps += [ ":$_res_target_name" ] | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | # Compatibility wrapper to toggle android_deps usage for a dependency. | 
|  | # | 
|  | # This target creates a wrapper for a dependency allowing it to be loaded | 
|  | # either from //third_party/android_deps or from an existing //third_party | 
|  | # (or other) target. | 
|  | # | 
|  | # Variables | 
|  | #   fallback_target: Target to use when the android_deps repo is not enabled. | 
|  | #   android_deps_target_name: Name of the target from the android_deps repo to | 
|  | #     use when the repo is enabled. Is not set, the wrapper's target name will | 
|  | #     be used instead. | 
|  | # | 
|  | # Example | 
|  | #   prebuilt_wrapper("android_support_multidex_java") { | 
|  | #     android_deps_target_name = "com_android_support_multidex_java" | 
|  | #     fallback_target = "$android_support_library_package:$target_name" | 
|  | #   } | 
|  | template("prebuilt_wrapper") { | 
|  | if (defined(invoker.android_deps_target_name)) { | 
|  | _resolved_android_deps_target_name = invoker.android_deps_target_name | 
|  | } else { | 
|  | _resolved_android_deps_target_name = target_name | 
|  | } | 
|  |  | 
|  | if (enable_android_deps_repository) { | 
|  | _resolved_target = | 
|  | "//third_party/android_deps:${_resolved_android_deps_target_name}" | 
|  | assert(invoker.fallback_target != "")  # Mark as used. | 
|  | } else { | 
|  | _resolved_target = "${invoker.fallback_target}" | 
|  | assert(_resolved_android_deps_target_name != "")  # Mark as used. | 
|  | } | 
|  |  | 
|  | java_group(target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  | deps = [ | 
|  | _resolved_target, | 
|  | ] | 
|  | } | 
|  | } |