# Copyright 2015 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.

import("//base/android/jni_generator/jni_exception_list.gni")
import("//build/buildflag_header.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//build/util/process_version.gni")
import("//build/util/version.gni")
import("//testing/test.gni")
import("//third_party/netty4/netty4.gni")
import("//third_party/protobuf/proto_library.gni")
import("//url/features.gni")

generate_jni("cronet_jni_headers") {
  sources = [
    "java/src/org/chromium/net/impl/CronetBidirectionalStream.java",
    "java/src/org/chromium/net/impl/CronetLibraryLoader.java",
    "java/src/org/chromium/net/impl/CronetUploadDataStream.java",
    "java/src/org/chromium/net/impl/CronetUrlRequest.java",
    "java/src/org/chromium/net/impl/CronetUrlRequestContext.java",
  ]
  jni_package = "cronet"
}

generate_jni_registration("cronet_jni_registration") {
  target = ":cronet_jni_apk"
  output = "$root_gen_dir/components/cronet/android/${target_name}.h"
  exception_files = jni_exception_files

  exception_files += [
    "//base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
    "//base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java",
    "//base/android/java/src/org/chromium/base/SysUtils.java",
  ]
}

java_cpp_enum("effective_connection_type_java") {
  sources = [
    "//net/nqe/effective_connection_type.h",
  ]
}

java_cpp_enum("rtt_throughput_values_java") {
  sources = [
    "//net/nqe/network_quality.h",
  ]
}

java_cpp_enum("net_request_priority_java") {
  sources = [
    "//net/base/request_priority.h",
  ]
}

java_cpp_enum("network_quality_observation_source_java") {
  sources = [
    "//net/nqe/network_quality_observation_source.h",
  ]
}

java_cpp_enum("url_request_error_java") {
  sources = [
    "url_request_error.h",
  ]
}

java_cpp_enum("http_cache_type_java") {
  sources = [
    "//components/cronet/url_request_context_config.h",
  ]
}

java_cpp_template("load_states_list") {
  sources = [
    "java/src/org/chromium/net/impl/LoadState.template",
  ]
  inputs = [
    "//net/base/load_states_list.h",
  ]
  package_path = "org/chromium/net/impl"
}

_generated_api_version_java_dir =
    "$target_gen_dir/templates/cronet_api_version_java"
_generated_api_version_java =
    "$_generated_api_version_java_dir/org/chromium/net/ApiVersion.java"

process_version("cronet_api_version_java") {
  _api_level = read_file("api_version.txt", "value")
  template_file = "api/src/org/chromium/net/ApiVersion.template"
  sources = [
    "//build/util/LASTCHANGE",
    "//chrome/VERSION",
  ]
  extra_args = [
    "-e",
    "API_LEVEL=$_api_level",
  ]
  output = _generated_api_version_java
}

zip("cronet_api_version_srcjar") {
  inputs = [
    _generated_api_version_java,
  ]
  output = "$target_gen_dir/$target_name.srcjar"
  base_dir = _generated_api_version_java_dir
  deps = [
    ":cronet_api_version_java",
  ]
}

_generated_impl_version_java_dir =
    "$target_gen_dir/templates/cronet_impl_version_java"
_generated_impl_version_java =
    "$_generated_impl_version_java_dir/org/chromium/net/impl/ImplVersion.java"

process_version("cronet_impl_version_java") {
  _api_level = read_file("api_version.txt", "value")
  template_file = "java/src/org/chromium/net/impl/ImplVersion.template"
  sources = [
    "//build/util/LASTCHANGE",
    "//chrome/VERSION",
  ]
  extra_args = [
    "-e",
    "API_LEVEL=$_api_level",
  ]
  output = _generated_impl_version_java
}

zip("cronet_impl_version_srcjar") {
  inputs = [
    _generated_impl_version_java,
  ]
  output = "$target_gen_dir/$target_name.srcjar"
  base_dir = _generated_impl_version_java_dir
  deps = [
    ":cronet_impl_version_java",
  ]
}

_cronet_version_header_include_dir = "$target_gen_dir/cronet_version_header"

source_set("cronet_static") {
  deps = [
    ":cronet_jni_headers",
    ":cronet_jni_registration",
    "//base",
    "//base/third_party/dynamic_annotations",
    "//components/cronet:cronet_common",
    "//components/cronet:cronet_version_header",
    "//components/cronet/native:cronet_native_impl",
    "//components/metrics",
    "//components/prefs",
    "//net",
    "//third_party/zlib:zlib",
    "//url",
    "//url:url_features",
  ]
  sources = [
    "//components/cronet/android/cronet_bidirectional_stream_adapter.cc",
    "//components/cronet/android/cronet_bidirectional_stream_adapter.h",
    "//components/cronet/android/cronet_library_loader.cc",
    "//components/cronet/android/cronet_library_loader.h",
    "//components/cronet/android/cronet_upload_data_stream_adapter.cc",
    "//components/cronet/android/cronet_upload_data_stream_adapter.h",
    "//components/cronet/android/cronet_url_request_adapter.cc",
    "//components/cronet/android/cronet_url_request_adapter.h",
    "//components/cronet/android/cronet_url_request_context_adapter.cc",
    "//components/cronet/android/cronet_url_request_context_adapter.h",
    "//components/cronet/android/io_buffer_with_byte_buffer.cc",
    "//components/cronet/android/io_buffer_with_byte_buffer.h",
    "//components/cronet/android/metrics_util.cc",
    "//components/cronet/android/metrics_util.h",
    "//components/cronet/android/url_request_error.cc",
    "//components/cronet/android/url_request_error.h",
  ]

  include_dirs = [ _cronet_version_header_include_dir ]

  cflags = [
    "-DLOGGING=1",
    "-Wno-sign-promo",
  ]

  libs = [
    "android",
    "log",
  ]

  if (!use_platform_icu_alternatives) {
    deps += [ "//base:i18n" ]
  }
}

config("hide_all_but_jni_onload_and_cronet") {
  ldflags = [ "-Wl,--version-script=" + rebase_path(
                  "//components/cronet/android/android_only_jni_onload_and_cronet_exports.lst") ]
}

_cronet_shared_lib_name = "cronet.$chrome_version_full"

shared_library("cronet") {
  output_name = _cronet_shared_lib_name
  sources = [
    "cronet_jni.cc",
  ]
  deps = [
    ":cronet_static",
    "//base",
    "//net:net",
  ]
  configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
  configs += [ ":hide_all_but_jni_onload_and_cronet" ]
}

cronet_api_srcjar_deps = [ ":cronet_api_version_srcjar" ]

# cronet_api_java.jar defines Cronet API.
android_library("cronet_api_java") {
  java_files = [
    "api/src/org/chromium/net/BidirectionalStream.java",
    "api/src/org/chromium/net/CronetEngine.java",
    "api/src/org/chromium/net/CallbackException.java",
    "api/src/org/chromium/net/CronetException.java",
    "api/src/org/chromium/net/CronetProvider.java",
    "api/src/org/chromium/net/ExperimentalBidirectionalStream.java",
    "api/src/org/chromium/net/ExperimentalCronetEngine.java",
    "api/src/org/chromium/net/ExperimentalUrlRequest.java",
    "api/src/org/chromium/net/ICronetEngineBuilder.java",
    "api/src/org/chromium/net/InlineExecutionProhibitedException.java",
    "api/src/org/chromium/net/NetworkException.java",
    "api/src/org/chromium/net/NetworkQualityRttListener.java",
    "api/src/org/chromium/net/NetworkQualityThroughputListener.java",
    "api/src/org/chromium/net/QuicException.java",
    "api/src/org/chromium/net/RequestFinishedInfo.java",
    "api/src/org/chromium/net/UploadDataProvider.java",
    "api/src/org/chromium/net/UploadDataProviders.java",
    "api/src/org/chromium/net/UploadDataSink.java",
    "api/src/org/chromium/net/UrlRequest.java",
    "api/src/org/chromium/net/UrlResponseInfo.java",
  ]

  deps = [
    "//third_party/android_tools:android_support_annotations_java",
  ]

  srcjar_deps = cronet_api_srcjar_deps
}

cronet_impl_common_java_srcjar_deps = [
  ":cronet_impl_version_srcjar",
  ":effective_connection_type_java",
  ":http_cache_type_java",
  ":load_states_list",
  ":rtt_throughput_values_java",
]

cronet_impl_common_java_deps_to_package =
    [ "//net/android:net_thread_stats_uid_java" ]

# cronet_impl_common_base_java.jar - common Cronet code that is shared
# by all Cronet engine implementations.
android_library("cronet_impl_common_base_java") {
  java_files = [
    "java/src/org/chromium/net/impl/CallbackExceptionImpl.java",
    "java/src/org/chromium/net/impl/CronetExceptionImpl.java",
    "java/src/org/chromium/net/impl/CronetEngineBase.java",
    "java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java",
    "java/src/org/chromium/net/impl/NetworkExceptionImpl.java",
    "java/src/org/chromium/net/impl/Preconditions.java",
    "java/src/org/chromium/net/impl/QuicExceptionImpl.java",
    "java/src/org/chromium/net/impl/RequestFinishedInfoImpl.java",
    "java/src/org/chromium/net/impl/UrlRequestBase.java",
    "java/src/org/chromium/net/impl/UrlRequestBuilderImpl.java",
    "java/src/org/chromium/net/impl/UrlResponseInfoImpl.java",
    "java/src/org/chromium/net/impl/UserAgent.java",
    "java/src/org/chromium/net/impl/VersionSafeCallbacks.java",
  ]

  # Adding deps here won't include those deps in the cronet_impl_common_java.jar.
  # Please add to cronet_impl_common_java_deps_to_package instead.
  deps = [
    ":cronet_api_java",
    "//third_party/android_tools:android_support_annotations_java",
  ]
  deps += cronet_impl_common_java_deps_to_package

  srcjar_deps = cronet_impl_common_java_srcjar_deps
}

# cronet_impl_platform_base_java.jar - Java platform based implementation of the Cronet engine.
android_library("cronet_impl_platform_base_java") {
  java_files = [
    "java/src/org/chromium/net/impl/InputStreamChannel.java",
    "java/src/org/chromium/net/impl/JavaCronetEngine.java",
    "java/src/org/chromium/net/impl/JavaCronetEngineBuilderImpl.java",
    "java/src/org/chromium/net/impl/JavaCronetProvider.java",
    "java/src/org/chromium/net/impl/JavaUrlRequest.java",
  ]

  deps = [
    ":cronet_api_java",
    ":cronet_impl_common_base_java",
    "//third_party/android_tools:android_support_annotations_java",
    "//third_party/jsr-305:jsr_305_javalib",
  ]
}

cronet_impl_native_java_srcjar_deps = [
  ":net_request_priority_java",
  ":network_quality_observation_source_java",
  ":url_request_error_java",
]

cronet_impl_native_java_deps_to_package = [
  "//base:base_java",
  "//net/android:net_java",
  "//url:url_java",
  ":cronet_urlconnection_impl_java",
]

android_library("cronet_urlconnection_impl_java") {
  java_files = [
    "java/src/org/chromium/net/urlconnection/CronetBufferedOutputStream.java",
    "java/src/org/chromium/net/urlconnection/CronetChunkedOutputStream.java",
    "java/src/org/chromium/net/urlconnection/CronetFixedModeOutputStream.java",
    "java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java",
    "java/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandler.java",
    "java/src/org/chromium/net/urlconnection/CronetInputStream.java",
    "java/src/org/chromium/net/urlconnection/CronetOutputStream.java",
    "java/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactory.java",
    "java/src/org/chromium/net/urlconnection/MessageLoop.java",
  ]
  deps = [
    ":cronet_api_java",
  ]
}

# cronet_impl_native_base_java.jar - native implementation of the Cronet engine.
android_library("cronet_impl_native_base_java") {
  java_files = [
    "java/src/org/chromium/net/impl/BidirectionalStreamBuilderImpl.java",
    "java/src/org/chromium/net/impl/BidirectionalStreamNetworkException.java",
    "java/src/org/chromium/net/impl/CronetBidirectionalStream.java",
    "java/src/org/chromium/net/impl/CronetLibraryLoader.java",
    "java/src/org/chromium/net/impl/CronetMetrics.java",
    "java/src/org/chromium/net/impl/CronetUploadDataStream.java",
    "java/src/org/chromium/net/impl/CronetUrlRequest.java",
    "java/src/org/chromium/net/impl/CronetUrlRequestContext.java",
    "java/src/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java",
    "java/src/org/chromium/net/impl/NativeCronetEngineBuilderWithLibraryLoaderImpl.java",
    "java/src/org/chromium/net/impl/NativeCronetProvider.java",
  ]

  # Adding deps here won't include those deps in the cronet_impl_native_java.jar.
  # Please add to cronet_impl_native_java_deps_to_package instead.
  deps = [
    ":cronet_api_java",
    ":cronet_impl_common_base_java",
    "//third_party/android_tools:android_support_annotations_java",
    "//third_party/jsr-305:jsr_305_javalib",
  ]
  deps += cronet_impl_native_java_deps_to_package

  srcjar_deps = cronet_impl_native_java_srcjar_deps
}

# Groups all Cronet implementations and the common code into a single Java dependency.
java_group("cronet_impl_all_java") {
  deps = [
    ":cronet_impl_common_base_java",
    ":cronet_impl_native_base_java",
    ":cronet_impl_platform_base_java",
  ]
}

# This target exists only to provide input to the generate_jni_registration
# target previously declared.  It contains all Java with JNI declarations.
android_apk("cronet_jni_apk") {
  apk_name = "CronetJni"
  android_manifest = "sample/AndroidManifest.xml"
  deps = [
    ":cronet_impl_all_java",
    "//third_party/android_tools:android_support_v7_appcompat_java",
  ]
}

android_resources("cronet_sample_apk_resources") {
  resource_dirs = [ "sample/res" ]
  android_manifest = "sample/AndroidManifest.xml"
  deps = [
    "//third_party/android_tools:android_support_v7_appcompat_java",
  ]
}

android_library("cronet_sample_apk_java") {
  java_files = [
    "sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java",
    "sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java",
  ]

  deps = [
    ":cronet_sample_apk_resources",
    ":package_api_java",
    ":package_impl_native_java",
    "//third_party/android_tools:android_support_v7_appcompat_java",
  ]
}

android_apk("cronet_sample_apk") {
  apk_name = "CronetSample"
  android_manifest = "sample/AndroidManifest.xml"
  shared_libraries = [ ":cronet" ]

  deps = [
    ":cronet_combine_proguard_flags",
    ":cronet_sample_apk_java",
    ":cronet_sample_apk_resources",
  ]

  # Cronet jars will include this, so don't duplicate.
  generate_buildconfig_java = false

  proguard_enabled = true
  proguard_configs = [
    "$target_gen_dir/cronet_impl_native_proguard.cfg",
    "cronet_impl_common_proguard.cfg",
    "//base/android/proguard/chromium_apk.flags",
  ]
}

action("cronet_combine_proguard_flags") {
  script = "//components/cronet/tools/generate_proguard_file.py"
  sources = [
    "//base/android/proguard/chromium_code.flags",
    "//components/cronet/android/cronet_impl_native_proguard.cfg",
  ]
  outputs = [
    "$target_gen_dir/cronet_impl_native_proguard.cfg",
  ]
  args = [ "--output-file" ] + rebase_path(outputs, root_build_dir) +
         rebase_path(sources, root_build_dir)
}

_package_dir = "$root_out_dir/cronet"

# These package_* targets represent how Cronet is used in production code.
# Using these targets is preferred to using the underlying targets like
# :cronet_api_java or :cronet_impl_all_java, as it better tests production
# usage.
android_java_prebuilt("package_api_java") {
  jar_path = "$_package_dir/cronet_api.jar"
  deps = [
    ":copy_cronet_java8_jars_cronet_api_javaX",
  ]
}

android_java_prebuilt("package_impl_common_java") {
  jar_path = "$_package_dir/cronet_impl_common_java.jar"
  deps = [
    ":package_api_java",
    ":repackage_extracted_common_jars",
  ]
}

android_java_prebuilt("package_impl_native_java") {
  jar_path = "$_package_dir/cronet_impl_native_java.jar"
  deps = [
    ":package_api_java",
    ":package_impl_common_java",
    ":repackage_extracted_native_jars",
    "//third_party/jsr-305:jsr_305_javalib",
  ]
}

android_java_prebuilt("package_impl_platform_java") {
  jar_path = "$_package_dir/cronet_impl_platform_java.jar"
  deps = [
    ":copy_cronet_java8_jars_cronet_impl_platform_base_javaX",
    ":package_api_java",
    ":package_impl_common_java",
  ]
}

template("jar_src") {
  action(target_name) {
    _rebased_src_search_dirs =
        rebase_path(invoker.src_search_dirs, root_build_dir)

    script = "//components/cronet/tools/jar_src.py"
    depfile = "$target_gen_dir/$target_name.d"
    outputs = [
      invoker.jar_path,
    ]
    args = [
      "--src-search-dirs=${_rebased_src_search_dirs}",
      "--jar-path",
      rebase_path(invoker.jar_path, root_build_dir),
      "--depfile",
      rebase_path(depfile, root_build_dir),
    ]

    deps = []
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    _excluded_patterns = []
    if (defined(invoker.excluded_patterns)) {
      _excluded_patterns = invoker.excluded_patterns
    }
    _src_jars = []

    # Add src-jar files that are listed in "src_jars".
    if (defined(invoker.src_jars)) {
      _rebased_src_jars = rebase_path(invoker.src_jars, root_build_dir)
      _src_jars += _rebased_src_jars
    }

    # Add src-jar files that are generated by dependencies in "srcjar_deps".
    if (defined(invoker.srcjar_deps)) {
      foreach(_srcjar_dep, invoker.srcjar_deps) {
        _dep_gen_dir = get_label_info(_srcjar_dep, "target_gen_dir")
        _dep_name = get_label_info(_srcjar_dep, "name")
        _src_jars += rebase_path([ "$_dep_gen_dir/$_dep_name.srcjar" ])
        deps += [ _srcjar_dep ]
      }
    }

    # Create the list of all source files that are given in "src_files".
    _src_files = []
    if (defined(invoker.src_files)) {
      _src_files += invoker.src_files
    }

    # Handle "source_deps".
    _src_list_files = []
    if (defined(invoker.source_deps)) {
      foreach(_source_dep, invoker.source_deps) {
        _dep_gen_dir = get_label_info(_source_dep, "target_gen_dir")
        _dep_name = get_label_info(_source_dep, "name")
        _src_list_files += rebase_path([ "$_dep_gen_dir/$_dep_name.sources" ])
        deps += [ _source_dep ]
      }
    }
    args += [ "--src-jar=${_src_jars}" ]
    args += [ "--src-files=${_src_files}" ]
    args += [ "--src-list-files=${_src_list_files}" ]
    args += [ "--excluded-classes=$_excluded_patterns" ]

    inputs = _src_jars
    inputs += _src_files
    inputs += _src_list_files
  }
}

jar_src("jar_cronet_api_source") {
  src_search_dirs = [ "api/src" ]
  source_deps = [ ":cronet_api_java" ]
  srcjar_deps = cronet_api_srcjar_deps
  jar_path = "$_package_dir/cronet_api-src.jar"
}

jar_src("jar_cronet_impl_common_java_source") {
  src_search_dirs = [ "java/src" ]
  source_deps = [ ":cronet_impl_common_base_java" ]
  srcjar_deps = cronet_impl_common_java_srcjar_deps
  jar_path = "$_package_dir/cronet_impl_common_java-src.jar"
}

jar_src("jar_cronet_impl_platform_java_source") {
  src_search_dirs = [ "java/src" ]
  source_deps = [ ":cronet_impl_platform_base_java" ]
  jar_path = "$_package_dir/cronet_impl_platform_java-src.jar"
}

template("copy_java8_jars") {
  _deps = []
  foreach(_dep, invoker.deps) {
    _dep_name = get_label_info(_dep, "name")
    _source_jar =
        get_label_info(_dep, "target_gen_dir") + "/" + _dep_name + ".javac.jar"
    _output_jar = "$_package_dir/" + _dep_name + ".jar"

    # Adjust file names that are different from the target name that builds it.
    if (_output_jar == "$_package_dir/" + "cronet_api_java.jar") {
      _output_jar = "$_package_dir/" + "cronet_api.jar"
    }
    if (_output_jar == "$_package_dir/" + "cronet_impl_platform_base_java.jar") {
      _output_jar = "$_package_dir/" + "cronet_impl_platform_java.jar"
    }

    # _deps have targets which match the java target whitelist. Add a
    # trailing X to avoid the copy() target matching the whitelist.
    # See _java_target_whitelist in build/config/android/internal_rules.gni.
    _copy_target_name = "${target_name}_${_dep_name}X"
    copy(_copy_target_name) {
      sources = [
        _source_jar,
      ]
      outputs = [
        _output_jar,
      ]
      deps = [
        ":$_dep_name",
      ]
    }

    _deps += [ ":" + _copy_target_name ]
  }

  group(target_name) {
    deps = _deps
  }
}

copy_java8_jars("copy_cronet_java8_jars") {
  deps = [
    ":cronet_api_java",
    ":cronet_impl_platform_base_java",
  ]
}

_extract_cronet_native_jars_dir = "$target_gen_dir/cronet_native_jar_extract"
_extract_cronet_common_jars_dir = "$target_gen_dir/cronet_common_jar_extract"

# List of patterns of .class files to exclude from the jar.
jar_excluded_patterns = [
  # Excludes Android support libraries crbug.com/832770.
  "android/*",
  "*/library_loader/*.class",
  "*/multidex/*.class",
  "*/process_launcher/*.class",
  "*/SysUtils.class",
  "*/CachedMetrics*.class",
  "org/chromium/base/memory/MemoryPressureMonitor*.class",
]

action("extract_cronet_native_jars") {
  # extract_from_jars.py deletes the target directory before extracting.
  script = "//components/cronet/tools/extract_from_jars.py"
  depfile = "$target_gen_dir/$target_name.d"

  _stamp_file = "$target_gen_dir/$target_name.stamp"
  outputs = [
    _stamp_file,
  ]

  deps = [
    ":cronet_impl_native_base_java",
  ]
  deps += cronet_impl_native_java_deps_to_package

  sources = []

  # Extract pre-desugared jar for each dependency.
  foreach(dep, deps) {
    sources += [ get_label_info(dep, "target_gen_dir") + "/" +
                 get_label_info(dep, "name") + ".javac.jar" ]
  }

  _rebased_sources = rebase_path(sources, root_build_dir)

  args = [
    "--classes-dir",
    rebase_path(_extract_cronet_native_jars_dir, root_build_dir),
    "--jars=${_rebased_sources}",
    "--depfile",
    rebase_path(depfile, root_build_dir),
    "--stamp",
    rebase_path(_stamp_file, root_build_dir),
  ]
}

action("repackage_extracted_native_jars") {
  _output_jar = "$_package_dir/cronet_impl_native_java.jar"

  script = "//build/android/gyp/jar.py"
  outputs = [
    _output_jar,
  ]

  args = [
    "--classes-dir",
    rebase_path(_extract_cronet_native_jars_dir, root_build_dir),
    "--excluded-classes=$jar_excluded_patterns",
    "--jar-path",
    rebase_path(_output_jar, root_build_dir),
  ]

  deps = [
    ":extract_cronet_native_jars",
  ]
}

action("extract_cronet_common_jars") {
  # extract_from_jars.py deletes the target directory before extracting.
  script = "//components/cronet/tools/extract_from_jars.py"
  depfile = "$target_gen_dir/$target_name.d"

  _stamp_file = "$target_gen_dir/$target_name.stamp"
  outputs = [
    _stamp_file,
  ]

  deps = [
    ":cronet_impl_common_base_java",
  ]
  deps += cronet_impl_common_java_deps_to_package

  sources = []

  # Extract pre-desugared jar for each dependency.
  foreach(dep, deps) {
    sources += [ get_label_info(dep, "target_gen_dir") + "/" +
                 get_label_info(dep, "name") + ".javac.jar" ]
  }

  _rebased_sources = rebase_path(sources, root_build_dir)

  args = [
    "--classes-dir",
    rebase_path(_extract_cronet_common_jars_dir, root_build_dir),
    "--jars=${_rebased_sources}",
    "--depfile",
    rebase_path(depfile, root_build_dir),
    "--stamp",
    rebase_path(_stamp_file, root_build_dir),
  ]
}

action("repackage_extracted_common_jars") {
  _output_jar = "$_package_dir/cronet_impl_common_java.jar"

  script = "//build/android/gyp/jar.py"
  outputs = [
    _output_jar,
  ]

  args = [
    "--classes-dir",
    rebase_path(_extract_cronet_common_jars_dir, root_build_dir),
    "--jar-path",
    rebase_path(_output_jar, root_build_dir),
  ]

  deps = [
    ":extract_cronet_common_jars",
  ]
}

if (!is_component_build) {
  _cronet_shared_lib_file_name = "lib" + _cronet_shared_lib_name + ".so"

  # cronet_sample_test_apk_resources is identical to
  # cronet_sample_apk_resources. The two have to be different targets because
  # targets which are common between the "instrumentation test apk" and the
  # "tested apk" are removed from the "instrumentation test apk".
  android_resources("cronet_sample_test_apk_resources") {
    resource_dirs = [ "sample/res" ]
    android_manifest = "sample/javatests/AndroidManifest.xml"
  }

  instrumentation_test_apk("cronet_sample_test_apk") {
    apk_name = "CronetSampleTest"
    apk_under_test = ":cronet_sample_apk"
    android_manifest = "sample/javatests/AndroidManifest.xml"
    java_files = [ "sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java" ]
    deps = [
      "//third_party/android_support_test_runner:rules_java",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/junit",
    ]

    proguard_enabled = true
    proguard_configs = [ "sample/javatests/proguard.cfg" ]
  }

  generate_jni("cronet_tests_jni_headers") {
    testonly = true
    sources = [
      "test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java",
      "test/javatests/src/org/chromium/net/CronetUrlRequestTest.java",
      "test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java",
      "test/src/org/chromium/net/CronetTestUtil.java",
      "test/src/org/chromium/net/MockCertVerifier.java",
      "test/src/org/chromium/net/MockUrlRequestJobFactory.java",
      "test/src/org/chromium/net/NativeTestServer.java",
      "test/src/org/chromium/net/QuicTestServer.java",
      "test/src/org/chromium/net/TestUploadDataStreamHandler.java",
    ]
    jni_package = "cronet_tests"
  }

  shared_library("cronet_tests") {
    testonly = true
    sources = [
      # While "cronet_tests" cannot depend on "cronet_static", and hence cannot
      # call any Cronet functions, it can access fields of Cronet objects, so add
      # Cronet header files to facilitate accessing these fields.
      "//components/cronet/android/cronet_url_request_adapter.h",
      "//components/cronet/android/cronet_url_request_context_adapter.h",
      "//components/cronet/cronet_url_request.h",
      "//components/cronet/cronet_url_request_context.h",
      "//components/cronet/url_request_context_config.h",
      "test/cronet_test_jni.cc",
      "test/cronet_test_util.cc",
      "test/cronet_test_util.h",
      "test/cronet_url_request_context_config_test.cc",
      "test/cronet_url_request_context_config_test.h",
      "test/cronet_url_request_test.cc",
      "test/experimental_options_test.cc",
      "test/mock_cert_verifier.cc",
      "test/mock_url_request_job_factory.cc",
      "test/native_test_server.cc",
      "test/quic_test_server.cc",
      "test/test_upload_data_stream_handler.cc",
      "test/test_upload_data_stream_handler.h",
    ]

    deps = [
      ":cronet",
      ":cronet_tests_jni_headers",
      "//base",
      "//base:i18n",
      "//base/test:test_support",
      "//components/cronet:cronet_version_header",
      "//components/cronet/test:test_support",
      "//components/prefs",
      "//net",
      "//net:simple_quic_tools",
      "//net:test_support",
      "//third_party/icu",
    ]

    include_dirs = [ _cronet_version_header_include_dir ]

    configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
    configs += [ "//build/config/android:hide_all_but_jni" ]
  }

  android_resources("cronet_test_apk_resources") {
    testonly = true
    resource_dirs = [
      "test/res",
      "test/smoketests/res/native",
    ]
    android_manifest = "test/AndroidManifest.xml"
  }

  android_library("cronet_test_apk_java") {
    testonly = true

    java_files = [
      "test/src/org/chromium/net/CronetTestApplication.java",
      "test/src/org/chromium/net/CronetTestUtil.java",
      "test/src/org/chromium/net/Http2TestHandler.java",
      "test/src/org/chromium/net/Http2TestServer.java",
      "test/src/org/chromium/net/MockCertVerifier.java",
      "test/src/org/chromium/net/MockUrlRequestJobFactory.java",
      "test/src/org/chromium/net/NativeTestServer.java",
      "test/src/org/chromium/net/QuicTestServer.java",
      "test/src/org/chromium/net/TestFilesInstaller.java",
      "test/src/org/chromium/net/TestUploadDataStreamHandler.java",
    ]

    deps = [
      ":cronet_api_java",
      ":cronet_impl_all_java",
      "//base:base_java",
      "//base:base_java_test_support",
      "//net/android:net_java_test_support",
      "//third_party/junit",
      "//third_party/netty4:netty_all_java",
    ]
  }

  cronet_smoketests_platform_only_common_srcs = [
    "test/smoketests/src/org/chromium/net/smoke/ChromiumPlatformOnlyTestSupport.java",
    "test/smoketests/src/org/chromium/net/smoke/CronetSmokeTestRule.java",
    "test/smoketests/src/org/chromium/net/smoke/HttpTestServer.java",
    "test/smoketests/src/org/chromium/net/smoke/SmokeTestRequestCallback.java",
    "test/smoketests/src/org/chromium/net/smoke/TestSupport.java",
  ]

  cronet_smoketests_native_common_srcs = cronet_smoketests_platform_only_common_srcs + [
                                           "test/smoketests/src/org/chromium/net/smoke/ChromiumNativeTestSupport.java",
                                           "test/smoketests/src/org/chromium/net/smoke/NativeCronetTestRule.java",
                                         ]

  android_library("cronet_smoketests_native_java") {
    testonly = true
    java_files = [
                   "test/smoketests/src/org/chromium/net/smoke/Http2Test.java",
                   "test/smoketests/src/org/chromium/net/smoke/QuicTest.java",
                 ] + cronet_smoketests_native_common_srcs

    deps = [
      ":cronet_api_java",
      ":cronet_test_apk_java",
      "//base:base_java",
      "//base:base_java_test_support",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/junit",
      "//third_party/netty4:netty_all_java",
    ]
  }

  android_apk("cronet_test_apk") {
    testonly = true
    apk_name = "CronetTest"
    android_manifest = "test/AndroidManifest.xml"
    shared_libraries = [
      ":cronet",
      ":cronet_tests",
    ]
    loadable_modules = [ "$root_out_dir/libnetty-tcnative.so" ]

    deps = [
      ":cronet_combine_proguard_flags",
      ":cronet_test_apk_resources",
      "//base:base_java",
      "//third_party/netty-tcnative:netty-tcnative-so",
    ]

    proguard_enabled = true

    proguard_configs = [
      "$target_gen_dir/cronet_impl_native_proguard.cfg",
      "cronet_impl_common_proguard.cfg",
      "cronet_impl_platform_proguard.cfg",
    ]
  }

  cronet_javatests_deps_to_package = [
    ":cronet_test_apk_java",
    "//base:base_java",
    "//base:base_java_test_support",
    "//net/android:embedded_test_server_aidl_java",
    "//net/android:net_java",
    "//net/android:net_java_test_support",
    "//url:url_java",
  ]

  android_library("cronet_javatests") {
    testonly = true

    java_files = [
      "test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java",
      "test/javatests/src/org/chromium/net/BidirectionalStreamTest.java",
      "test/javatests/src/org/chromium/net/BrotliTest.java",
      "test/javatests/src/org/chromium/net/Criteria.java",
      "test/javatests/src/org/chromium/net/CronetEngineBuilderTest.java",
      "test/javatests/src/org/chromium/net/CronetStressTest.java",
      "test/javatests/src/org/chromium/net/CronetTestRule.java",
      "test/javatests/src/org/chromium/net/CronetTestRuleTest.java",
      "test/javatests/src/org/chromium/net/CronetUploadTest.java",
      "test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java",
      "test/javatests/src/org/chromium/net/CronetUrlRequestTest.java",
      "test/javatests/src/org/chromium/net/DiskStorageTest.java",
      "test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java",
      "test/javatests/src/org/chromium/net/GetStatusTest.java",
      "test/javatests/src/org/chromium/net/MetricsTestUtil.java",
      "test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java",
      "test/javatests/src/org/chromium/net/NQETest.java",
      "test/javatests/src/org/chromium/net/PkpTest.java",
      "test/javatests/src/org/chromium/net/QuicTest.java",
      "test/javatests/src/org/chromium/net/RequestFinishedInfoTest.java",
      "test/javatests/src/org/chromium/net/TestBidirectionalStreamCallback.java",
      "test/javatests/src/org/chromium/net/TestDrivenDataProvider.java",
      "test/javatests/src/org/chromium/net/TestNetworkQualityRttListener.java",
      "test/javatests/src/org/chromium/net/TestNetworkQualityThroughputListener.java",
      "test/javatests/src/org/chromium/net/TestUploadDataProvider.java",
      "test/javatests/src/org/chromium/net/TestUrlRequestCallback.java",
      "test/javatests/src/org/chromium/net/UploadDataProvidersTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/CronetBufferedOutputStreamTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/CronetChunkedOutputStreamTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/CronetFixedModeOutputStreamTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLConnectionTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/CronetURLStreamHandlerFactoryTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/MessageLoopTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/QuicUploadTest.java",
      "test/javatests/src/org/chromium/net/urlconnection/TestUtil.java",
      "test/javatests/src/org/chromium/net/UrlResponseInfoTest.java",
    ]

    # Adding deps here won't include those deps in the cronet_tests_java.jar.
    # Please add to cronet_javatests_deps_to_package instead.
    deps = [
      ":cronet_api_java",
      ":cronet_impl_all_java",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/junit",
    ]
    deps += cronet_javatests_deps_to_package
    data = [
      "//components/cronet/test/data/",
    ]
  }

  instrumentation_test_apk("cronet_test_instrumentation_apk") {
    apk_name = "CronetTestInstrumentation"
    apk_under_test = ":cronet_test_apk"
    android_manifest = "test/javatests/AndroidManifest.xml"

    deps = [
      ":cronet_api_java",
      ":cronet_impl_all_java",
      ":cronet_javatests",
      ":cronet_smoketests_native_java",
      ":cronet_test_apk_java",
      "//base:base_java",
      "//base:base_java_test_support",
      "//net/android:net_java",
      "//net/android:net_java_test_support",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/android_tools:android_test_mock_java",
      "//third_party/hamcrest:hamcrest_core_java",
    ]
    additional_apks = [ "//net/android:net_test_support_apk" ]

    data_deps = [
      "//net:test_support",
    ]

    proguard_enabled = true

    proguard_configs = [ "test/proguard.cfg" ]
  }

  android_resources("cronet_smoketests_platform_only_apk_resources") {
    testonly = true
    resource_dirs = [ "test/smoketests/res/platform_only" ]
    android_manifest = "test/AndroidManifest.xml"
  }

  android_library("cronet_smoketests_platform_only_java") {
    testonly = true
    java_files = [ "test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java" ] + cronet_smoketests_platform_only_common_srcs
    deps = [
      ":cronet_api_java",
      "//base:base_java_test_support",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/junit",
      "//third_party/netty4:netty_all_java",
    ]
  }

  android_apk("cronet_smoketests_platform_only_apk") {
    testonly = true
    apk_name = "PlatformOnlyEngineSmokeTest"
    android_manifest = "test/AndroidManifest.xml"
    java_files = [ "test/src/org/chromium/net/CronetTestApplication.java" ]

    proguard_enabled = true
    proguard_configs = [
      "cronet_impl_common_proguard.cfg",
      "cronet_impl_platform_proguard.cfg",
    ]

    deps = [
      ":cronet_api_java",
      ":cronet_impl_common_base_java",
      ":cronet_impl_platform_base_java",
      ":cronet_smoketests_platform_only_apk_resources",
    ]
  }

  instrumentation_test_apk(
      "cronet_smoketests_platform_only_instrumentation_apk") {
    apk_name = "PlatformOnlyEngineSmokeTestInstrumentation"
    apk_under_test = ":cronet_smoketests_platform_only_apk"
    android_manifest = "test/javatests/AndroidManifest.xml"
    deps = [
      ":cronet_smoketests_platform_only_java",
      "//base:base_java_test_support",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/android_tools:android_test_mock_java",
    ]

    proguard_enabled = true

    proguard_configs = [ "test/proguard.cfg" ]
  }

  android_library("cronet_smoketests_missing_native_library_java") {
    testonly = true
    java_files = [ "test/smoketests/src/org/chromium/net/smoke/MissingNativeLibraryTest.java" ] + cronet_smoketests_native_common_srcs
    deps = [
      ":cronet_api_java",
      ":cronet_test_apk_java",
      "//base:base_java",
      "//base:base_java_test_support",
      "//third_party/android_support_test_runner:runner_java",
      "//third_party/junit",
      "//third_party/netty4:netty_all_java",
    ]
  }

  android_apk("cronet_smoketests_missing_native_library_apk") {
    testonly = true
    apk_name = "MissingNativeLibrarySmokeTest"
    android_manifest = "test/AndroidManifest.xml"
    deps = [
      ":cronet_api_java",
      ":cronet_combine_proguard_flags",
      ":cronet_impl_common_base_java",
      ":cronet_impl_platform_base_java",
      ":cronet_test_apk_resources",
    ]

    proguard_enabled = true
    proguard_configs = [
      "$target_gen_dir/cronet_impl_native_proguard.cfg",
      "cronet_impl_common_proguard.cfg",
      "cronet_impl_platform_proguard.cfg",
    ]
  }

  instrumentation_test_apk(
      "cronet_smoketests_missing_native_library_instrumentation_apk") {
    apk_name = "MissingNativeLibrarySmokeTestInstrumentation"
    apk_under_test = ":cronet_smoketests_missing_native_library_apk"
    android_manifest = "test/javatests/AndroidManifest.xml"

    deps = [
      ":cronet_smoketests_missing_native_library_java",
      "//third_party/android_tools:android_test_mock_java",
    ]

    proguard_enabled = true

    proguard_configs = [ "test/proguard.cfg" ]
  }

  android_library("cronet_perf_test_apk_java") {
    testonly = true
    android_manifest_for_lint = "test/javaperftests/AndroidManifest.xml"
    java_files = [
      "test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java",
    ]

    deps = [
      ":cronet_api_java",
      ":cronet_impl_all_java",
      ":cronet_javatests",
      ":cronet_test_apk_java",
      "//base:base_java",
    ]
  }

  android_apk("cronet_perf_test_apk") {
    testonly = true
    apk_name = "CronetPerfTest"
    android_manifest = "test/javaperftests/AndroidManifest.xml"
    shared_libraries = [
      ":cronet",
      ":cronet_tests",
    ]

    deps = [
      ":cronet_combine_proguard_flags",
      ":cronet_perf_test_apk_java",
      ":cronet_test_apk_java",
      "//base:base_java",
      "//third_party/android_tools:android_test_mock_java",
    ]

    proguard_enabled = true
    proguard_configs = [
      "$target_gen_dir/cronet_impl_native_proguard.cfg",
      "cronet_impl_common_proguard.cfg",
      "test/proguard.cfg",
      "//base/android/proguard/chromium_apk.flags",
    ]
  }

  test("cronet_unittests_android") {
    deps = [
      ":cronet_impl_native_base_java",
      ":cronet_static",
      "//base",
      "//base/test:test_support",
      "//components/cronet:cronet_common_unittests",
      "//components/cronet/native:cronet_native_unittests",
      "//components/cronet/native/test:cronet_native_tests",
      "//components/metrics",
      "//components/prefs:test_support",
      "//net",
      "//net:test_support",
      "//net/android:net_java",
      "//testing/gtest",
    ]

    data = [
      "//components/cronet/test/data/",
    ]

    if (is_android) {
      shard_timeout = 180
    }
  }

  _test_package_dir = "$root_out_dir/cronet/test"
  _extract_cronet_test_jars_dir = "$target_gen_dir/cronet_test_jar_extract"

  cronet_test_deps = [ ":cronet_javatests" ]
  cronet_test_deps += cronet_javatests_deps_to_package

  action("extract_cronet_test_jars") {
    # extract_from_jars.py deletes the target directory before extracting.
    script = "//components/cronet/tools/extract_from_jars.py"
    depfile = "$target_gen_dir/$target_name.d"
    testonly = true

    sources = [
      NETTY4_JAR_FILE,
    ]

    # Extract pre-desugared jar for each cronet_test_deps.
    foreach(dep, cronet_test_deps) {
      sources += [ get_label_info(dep, "target_gen_dir") + "/" +
                   get_label_info(dep, "name") + ".javac.jar" ]
    }

    _stamp_file = "$target_gen_dir/$target_name.stamp"
    outputs = [
      _stamp_file,
    ]

    _rebased_sources = rebase_path(sources, root_build_dir)

    args = [
      "--classes-dir",
      rebase_path(_extract_cronet_test_jars_dir, root_build_dir),
      "--jars=${_rebased_sources}",
      "--depfile",
      rebase_path(depfile, root_build_dir),
      "--stamp",
      rebase_path(_stamp_file, root_build_dir),
    ]

    deps = [
      "//third_party/netty4:netty_all_java",
    ]
    deps += cronet_test_deps
  }

  action("repackage_extracted_test_jars") {
    _output_jar = "$_test_package_dir/cronet_tests_java.jar"
    testonly = true

    script = "//build/android/gyp/jar.py"
    outputs = [
      _output_jar,
    ]

    args = [
      "--classes-dir",
      rebase_path(_extract_cronet_test_jars_dir, root_build_dir),
      "--jar-path",
      rebase_path(_output_jar, root_build_dir),
    ]

    deps = [
      ":extract_cronet_test_jars",
    ]
  }

  zip("jar_cronet_sample_source") {
    inputs = [
      "sample/AndroidManifest.xml",
      "sample/javatests/AndroidManifest.xml",
      "sample/javatests/proguard.cfg",
      "sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java",
      "sample/README",
      "sample/res/layout/activity_main.xml",
      "sample/res/layout/dialog_url.xml",
      "sample/res/values/dimens.xml",
      "sample/res/values/strings.xml",
      "sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java",
      "sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java",
    ]
    output = "$_package_dir/cronet-sample-src.jar"
    base_dir = "sample"
  }

  jar_src("jar_cronet_impl_native_java_source") {
    src_search_dirs = [
      "//base/android/java/src",
      "//components/cronet/android/java/src",
      "//net/android/java/src",
      "//url/android/java/src",
      "//third_party/android_async_task/java/src",
    ]
    source_deps = [
      ":cronet_impl_native_base_java",
      "//base:base_java",
      "//net/android:net_java",
      "//url:url_java",
    ]
    srcjar_deps = cronet_impl_native_java_srcjar_deps + [
                    "//base:base_android_java_enums_srcjar",
                    "//net/android:net_android_java_enums_srcjar",
                    "//net/android:net_errors_java",
                  ]
    excluded_patterns = jar_excluded_patterns
    jar_path = "$_package_dir/cronet_impl_native_java-src.jar"
  }

  action("generate_licenses") {
    _license_path = "$_package_dir/LICENSE"

    script = "//tools/licenses.py"
    outputs = [
      _license_path,
    ]
    args = [
      "license_file",
      rebase_path(_license_path, root_build_dir),
      "--gn-target",
      "//components/cronet/android:cronet",
      "--gn-out-dir",
      ".",
    ]
  }

  action("generate_javadoc") {
    script = "//components/cronet/tools/generate_javadoc.py"
    depfile = "$target_gen_dir/$target_name.d"
    _zip_file = "$target_gen_dir/$target_name.zip"
    outputs = [
      _zip_file,
    ]
    args = [
      "--output-dir",
      rebase_path(_package_dir, root_build_dir),
      "--input-dir",
      rebase_path("//components/cronet", root_build_dir),
      "--overview-file",
      rebase_path("$_package_dir/README.md.html", root_build_dir),
      "--readme-file",
      rebase_path("//components/cronet/README.md", root_build_dir),
      "--depfile",
      rebase_path(depfile, root_build_dir),
      "--zip-file",
      rebase_path(_zip_file, root_build_dir),

      "--android-sdk-jar",
      rebase_path(android_sdk_jar, root_build_dir),

      # JavaDoc is generated from Cronet's API source jar.
      "--input-src-jar",
      rebase_path("$_package_dir/cronet_api-src.jar", root_build_dir),
    ]
    deps = [
      ":jar_cronet_api_source",
    ]
  }

  copy("cronet_package_copy") {
    sources = [
      "$target_gen_dir/cronet_impl_native_proguard.cfg",
      "//AUTHORS",
      "//chrome/VERSION",
      "api_version.txt",
      "cronet_impl_common_proguard.cfg",
      "cronet_impl_platform_proguard.cfg",
    ]
    outputs = [
      "$_package_dir/{{source_file_part}}",
    ]

    deps = [
      ":cronet_api_java",
      ":cronet_combine_proguard_flags",
      ":cronet_impl_common_base_java",
      ":cronet_impl_platform_base_java",
    ]
  }

  copy("cronet_package_copy_native_lib") {
    sources = [
      "$root_out_dir/" + _cronet_shared_lib_file_name,
    ]
    outputs = [
      "$_package_dir/libs/${android_app_abi}/" + _cronet_shared_lib_file_name,
    ]
    deps = [
      ":cronet",
    ]
  }

  copy("cronet_package_copy_native_lib_unstripped") {
    sources = [
      "$root_out_dir/lib.unstripped/" + _cronet_shared_lib_file_name,
    ]
    outputs = [
      "$_package_dir/symbols/${android_app_abi}/" +
          _cronet_shared_lib_file_name,
    ]
    deps = [
      ":cronet",
    ]
  }

  copy("cronet_package_copy_native_test_lib") {
    testonly = true
    sources = [
      "$root_out_dir/libcronet_tests.so",
      "$root_out_dir/libnetty-tcnative.so",
    ]
    outputs = [
      "$_test_package_dir/libs/${android_app_abi}/{{source_file_part}}",
    ]
    deps = [
      ":cronet_tests",
      "//third_party/netty-tcnative:netty-tcnative-so",
    ]
  }

  copy("cronet_package_copy_native_test_lib_unstripped") {
    testonly = true
    sources = [
      "$root_out_dir/lib.unstripped/libcronet_tests.so",
      "$root_out_dir/lib.unstripped/libnetty-tcnative.so",
    ]
    outputs = [
      "$_test_package_dir/symbols/${android_app_abi}/{{source_file_part}}",
    ]
    deps = [
      ":cronet_tests",
      "//third_party/netty-tcnative:netty-tcnative-so",
    ]
  }

  copy("cronet_package_copy_test_assets") {
    testonly = true
    sources = [
      "//components/cronet/test/data",
    ]
    outputs = [
      "$_test_package_dir/assets/test",
    ]
  }

  copy("cronet_package_copy_test_support_apks") {
    testonly = true
    sources = [
      # Provides EmbeddedTestServer.
      "$root_out_dir/apks/ChromiumNetTestSupport.apk",
    ]
    outputs = [
      "$_test_package_dir/apks/${android_app_abi}/{{source_file_part}}",
    ]
    deps = [
      "//net/android:net_test_support_apk",
    ]
  }

  copy("cronet_package_copy_test_files") {
    testonly = true
    sources = [
      "//net/data/ssl/certificates/quic-chain.pem",
      "//net/data/ssl/certificates/quic-leaf-cert.key",
      "//net/data/ssl/certificates/quic-leaf-cert.key.pkcs8.pem",
    ]
    outputs = [
      "$_test_package_dir/assets/test_files/net/data/ssl/certificates/{{source_file_part}}",
    ]
    deps = [
      # Not really dependent, but builds can fail if these two targets attempt
      # to create the "assets" subdirectory simultaneously.
      ":cronet_package_copy_test_assets",
    ]
  }

  copy("cronet_package_copy_resources") {
    sources = [
      "api/res/raw/keep_cronet_api.xml",
    ]
    outputs = [
      "$_package_dir/res/raw/{{source_file_part}}",
    ]
  }

  # Enforce that ARM Neon is not used when building for ARMv7
  if (target_cpu == "arm" && arm_version == 7 && !arm_use_neon) {
    action("enforce_no_neon") {
      script = "//components/cronet/tools/check_no_neon.py"
      outputs = [
        "$target_gen_dir/$target_name.stamp",
      ]
      args = [
        rebase_path("${android_tool_prefix}objdump", root_build_dir),

        # libcronet.so may contain ARM Neon instructions from BoringSSL, but these
        # are only used after checking whether the CPU supports NEON at runtime,
        # so instead check base/ as it represents a large swath of code that only
        # contains Neon instructions when Neon is enabled by default.
        rebase_path("$root_out_dir/obj/base/base/*.o", root_build_dir),
        "--stamp",
        rebase_path(outputs[0], root_build_dir),
      ]
      deps = [
        "//base:base",
      ]
    }
  }

  # Enforce restrictions for API<->impl boundary.
  action("api_static_checks") {
    script = "//components/cronet/tools/api_static_checks.py"
    outputs = [
      "$target_gen_dir/$target_name.stamp",
    ]
    args = [
      "--api_jar",
      rebase_path(
          "$root_out_dir/lib.java/components/cronet/android/cronet_api_java.jar",
          root_build_dir),
      "--impl_jar",
      rebase_path(
          "$root_out_dir/lib.java/components/cronet/android/cronet_impl_common_base_java.jar",
          root_build_dir),
      "--impl_jar",
      rebase_path(
          "$root_out_dir/lib.java/components/cronet/android/cronet_impl_platform_base_java.jar",
          root_build_dir),
      "--impl_jar",
      rebase_path(
          "$root_out_dir/lib.java/components/cronet/android/cronet_impl_native_base_java.jar",
          root_build_dir),
      "--stamp",
      rebase_path(outputs[0], root_build_dir),
    ]
    deps = [
      ":cronet_api_java",
      ":cronet_impl_common_base_java",
      ":cronet_impl_native_base_java",
      ":cronet_impl_platform_base_java",
    ]
    inputs = [
      "//components/cronet/tools/update_api.py",
    ]
    sources = [
      "//components/cronet/android/api.txt",
      "//components/cronet/android/api_version.txt",
    ]
  }

  group("cronet_package") {
    # Marked as testonly as it contains test-only targets too.
    testonly = true

    # Enforce building with ICU alternatives, crbug.com/611621.
    # Enforce that arm_use_neon==false when building for ARMv7 by
    # not including any deps in cronet_package target otherwise.
    if (use_platform_icu_alternatives &&
        (!(target_cpu == "arm" && arm_version == 7) || !arm_use_neon)) {
      deps = [
        ":api_static_checks",
        ":copy_cronet_java8_jars",
        ":cronet_package_copy",
        ":cronet_package_copy_native_lib",
        ":cronet_package_copy_native_lib_unstripped",
        ":cronet_package_copy_resources",
        ":cronet_test_package",
        ":generate_javadoc",
        ":generate_licenses",
        ":jar_cronet_api_source",
        ":jar_cronet_impl_common_java_source",
        ":jar_cronet_impl_native_java_source",
        ":jar_cronet_impl_platform_java_source",
        ":jar_cronet_sample_source",
        ":repackage_extracted_common_jars",
        ":repackage_extracted_native_jars",
      ]
      if (current_cpu == "arm" && arm_version == 7) {
        deps += [ ":enforce_no_neon" ]
      }
    }
  }

  group("cronet_test_package") {
    testonly = true

    # Don't build for MIPS where tests aren't run.
    if (current_cpu != "mipsel" && current_cpu != "mips64el") {
      deps = [
        ":cronet_package_copy_native_test_lib",
        ":cronet_package_copy_native_test_lib_unstripped",
        ":cronet_package_copy_test_assets",
        ":cronet_package_copy_test_files",
        ":cronet_package_copy_test_support_apks",
        ":repackage_extracted_test_jars",
      ]
    }
  }

  _maven_dir = "$_package_dir/maven-$current_cpu"
  _maven_modules_dir = "$_maven_dir/org/chromium/net"
  _maven_test_dir = "$_maven_dir/test"
  _maven_version =
      "$chrome_version_major.$chrome_version_build.$chrome_version_patch"

  copy("cronet_maven_test_copy") {
    sources = [
      "maven/build.gradle",
      "maven/local.properties",
      "maven/settings.gradle",
    ]
    outputs = [
      "$_maven_test_dir/{{source_file_part}}",
    ]
  }

  process_version("cronet_maven_build_embedded_copy") {
    template_file = "maven/test/build_embedded.gradle.template"
    sources = [
      "//build/util/LASTCHANGE",
      "//chrome/VERSION",
    ]
    output = "$_maven_test_dir/test_embedded/build.gradle"
  }

  process_version("cronet_maven_build_fallback_copy") {
    template_file = "maven/test/build_fallback.gradle.template"
    sources = [
      "//build/util/LASTCHANGE",
      "//chrome/VERSION",
    ]
    output = "$_maven_test_dir/test_fallback/build.gradle"
  }

  if (use_platform_icu_alternatives) {
    action("cronet_maven_test_build") {
      script = "maven/test/build_with_gradle.py"
      depfile = "$target_gen_dir/$target_name.d"
      deps = [
        ":cronet_maven_build_embedded_copy",
        ":cronet_maven_build_fallback_copy",
        ":cronet_maven_modules",
        ":cronet_maven_test_copy",

        # These deps ensure all source files of the sample app are deps.
        ":cronet_sample_apk",
        ":cronet_sample_test_apk",
      ]
      _stamp_file = "$target_gen_dir/$target_name.stamp"
      outputs = [
        _stamp_file,
        "$_maven_test_dir/build/outputs/apk/debug/test-debug.apk",
        "$_maven_test_dir/build/outputs/apk/androidTest/debug/test-debug-androidTest.apk",
      ]
      args = [
        "--project-dir",
        rebase_path("$_maven_test_dir"),
        "--depfile",
        rebase_path(depfile, root_build_dir),
        "--stamp",
        rebase_path(_stamp_file, root_build_dir),
      ]
      testonly = true
    }
  }

  # Builds a maven module.
  template("cronet_maven_module") {
    _module_name = invoker.module_name

    # Build POM file.
    _pom_target_name = "pom_$target_name"
    _deps = [ ":$_pom_target_name" ]
    process_version(_pom_target_name) {
      template_file = "maven/$_module_name.pom.template"
      sources = [
        "//build/util/LASTCHANGE",
        "//chrome/VERSION",
      ]
      output = "$_maven_modules_dir/$_module_name/$_maven_version/$_module_name-$_maven_version.pom"
    }

    if (defined(invoker.resource_dir)) {
      android_resources(invoker.module_name + "_resources") {
        resource_dirs = [ invoker.resource_dir ]
        android_manifest = "../../../build/android/AndroidManifest.xml"
      }
    }

    # Build AAR file.
    _aar_target_name = "aar_$target_name"
    dist_aar(_aar_target_name) {
      deps = [
        ":cronet_package_copy",
        invoker.aar_jar_dep,
      ]
      direct_deps_only = true
      if (defined(invoker.aar_proguard_config)) {
        proguard_configs = [ invoker.aar_proguard_config ]
      }
      if (defined(invoker.aar_native_lib_dep)) {
        native_libraries = get_target_outputs(invoker.aar_native_lib_dep)
        deps += [ invoker.aar_native_lib_dep ]
      }
      if (defined(invoker.resource_dir)) {
        deps += [ ":" + invoker.module_name + "_resources" ]
      }
      output = "$root_build_dir/$_aar_target_name.aar"
    }

    _aar_copy_target_name = "$target_name.aar"
    _deps += [ ":$_aar_copy_target_name" ]
    copy(_aar_copy_target_name) {
      sources = get_target_outputs(":$_aar_target_name")
      outputs = [
        "$_maven_modules_dir/$_module_name/$_maven_version/$_module_name-$_maven_version.aar",
      ]
      deps = [
        ":$_aar_target_name",
      ]
    }

    if (defined(invoker.src_jar_dep)) {
      _copy_target_name = "$target_name-sources.jar"
      _deps += [ ":$_copy_target_name" ]
      copy(_copy_target_name) {
        sources = get_target_outputs(invoker.src_jar_dep)
        outputs = [
          "$_maven_modules_dir/$_module_name/$_maven_version/$_module_name-$_maven_version-sources.jar",
        ]
        deps = [
          invoker.src_jar_dep,
        ]
      }
    }

    if (defined(invoker.javadoc_jar_dep)) {
      _copy_target_name = "$target_name-javadoc.jar"
      _deps += [ ":$_copy_target_name" ]
      copy(_copy_target_name) {
        sources = get_target_outputs(invoker.javadoc_jar_dep)
        outputs = [
          "$_maven_modules_dir/$_module_name/$_maven_version/$_module_name-$_maven_version-javadoc.jar",
        ]
        deps = [
          invoker.javadoc_jar_dep,
        ]
      }
    }

    group(target_name) {
      deps = _deps
    }
  }

  cronet_maven_module("cronet_maven_api_module") {
    module_name = "cronet-api"
    aar_jar_dep = ":package_api_java"
    src_jar_dep = ":jar_cronet_api_source"
    javadoc_jar_dep = ":generate_javadoc"
    resource_dir = "api/res"
  }

  cronet_maven_module("cronet_maven_impl_common_module") {
    module_name = "cronet-common"
    aar_jar_dep = ":package_impl_common_java"
    aar_proguard_config = "$_package_dir/cronet_impl_common_proguard.cfg"
    src_jar_dep = ":jar_cronet_impl_common_java_source"
  }

  cronet_maven_module("cronet_maven_impl_native_module") {
    module_name = "cronet-embedded"
    aar_jar_dep = ":package_impl_native_java"
    aar_proguard_config = "$_package_dir/cronet_impl_native_proguard.cfg"
    aar_native_lib_dep = ":cronet_package_copy_native_lib"
    src_jar_dep = ":jar_cronet_impl_native_java_source"
  }

  cronet_maven_module("cronet_maven_impl_platform_module") {
    module_name = "cronet-fallback"
    aar_jar_dep = ":package_impl_platform_java"
    aar_proguard_config = "$_package_dir/cronet_impl_platform_proguard.cfg"
    src_jar_dep = ":jar_cronet_impl_platform_java_source"
  }

  group("cronet_maven_modules") {
    deps = [
      ":cronet_maven_api_module",
      ":cronet_maven_impl_common_module",
      ":cronet_maven_impl_native_module",
      ":cronet_maven_impl_platform_module",
    ]
  }
}
