diff --git a/src/components/cronet/BUILD.gn b/src/components/cronet/BUILD.gn
new file mode 100644
index 0000000000..2db3d1fd4a
--- /dev/null
+++ b/src/components/cronet/BUILD.gn
@@ -0,0 +1,271 @@
+# Copyright 2017 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("//build/buildflag_header.gni")
+import("//build/toolchain/toolchain.gni")
+import("//build/util/lastchange.gni")
+import("//build/util/process_version.gni")
+import("//build/util/version.gni")
+import("//components/cronet/native/include/headers.gni")
+import("//components/grpc_support/include/headers.gni")
+import("//testing/test.gni")
+
+declare_args() {
+ # If set to true, this will remove histogram manager to reduce binary size.
+ disable_histogram_support = is_mac || is_win
+}
+
+# Disable histogram support is not allowed on Android.
+assert(!disable_histogram_support || !is_android)
+
+buildflag_header("cronet_buildflags") {
+ header = "cronet_buildflags.h"
+ flags = [ "DISABLE_HISTOGRAM_SUPPORT=$disable_histogram_support" ]
+}
+
+process_version("cronet_version_header") {
+ template_file = "//components/cronet/version.h.in"
+ sources = [ "//chrome/VERSION" ]
+ output = "$target_gen_dir/version.h"
+ extra_args = [
+ "-e",
+ "VERSION_FULL=\"%s.%s.%s.%s\" % (MAJOR,MINOR,BUILD,PATCH)",
+ ]
+}
+
+# Cronet common implementation.
+source_set("cronet_common") {
+ sources = [
+ "cronet_global_state.h",
+ "cronet_prefs_manager.cc",
+ "cronet_prefs_manager.h",
+ "cronet_upload_data_stream.cc",
+ "cronet_upload_data_stream.h",
+ "cronet_url_request.cc",
+ "cronet_url_request.h",
+ "cronet_url_request_context.cc",
+ "cronet_url_request_context.h",
+ "host_cache_persistence_manager.cc",
+ "host_cache_persistence_manager.h",
+ "stale_host_resolver.cc",
+ "stale_host_resolver.h",
+ "url_request_context_config.cc",
+ "url_request_context_config.h",
+ ]
+ deps = [
+ ":cronet_buildflags",
+ ":cronet_version_header",
+ "//base",
+ "//components/prefs:prefs",
+ "//net",
+ "//third_party/metrics_proto",
+ ]
+
+ if (!disable_histogram_support) {
+ public_deps = [ "//components/metrics:library_support" ]
+ }
+}
+
+source_set("metrics_util") {
+ sources = [
+ "metrics_util.cc",
+ "metrics_util.h",
+ ]
+ deps = [ "//base" ]
+}
+
+# Unit tests for Cronet common implementation.
+source_set("cronet_common_unittests") {
+ testonly = true
+
+ deps = [
+ ":cronet_common",
+ "//components/prefs:test_support",
+ "//net:test_support",
+ ]
+
+ sources = [
+ "host_cache_persistence_manager_unittest.cc",
+ "stale_host_resolver_unittest.cc",
+ "url_request_context_config_unittest.cc",
+ ]
+}
+
+# For platforms on which the native Cronet library is used, build the library,
+# a cronet_tests binary that exercises it, and a unit-tests binary.
+# Android and iOS have their own platform-specific rules to build Cronet.
+if (is_android) {
+ group("cronet_package") {
+ testonly = true
+ deps = [ "//components/cronet/android:cronet_package_android" ]
+ }
+} else if (is_ios) {
+ group("cronet_package") {
+ deps = [ "//components/cronet/ios:cronet_package_ios" ]
+ }
+} else {
+ config("shared_library_public_config") {
+ if (is_mac && !is_component_build) {
+ # Executable targets that depend on the shared libraries below need to have
+ # the rpath setup in non-component build configurations.
+ ldflags = [ "-Wl,-rpath,@executable_path/" ]
+ }
+ }
+
+ _cronet_shared_lib_name = "cronet.$chrome_version_full"
+ _cronet_shared_lib_file_name =
+ "$shlib_prefix$_cronet_shared_lib_name$shlib_extension"
+
+ shared_library("cronet") {
+ output_name = _cronet_shared_lib_name
+
+ deps = [
+ "//base",
+ "//components/cronet:cronet_common",
+ "//components/cronet/native:cronet_native_impl",
+ "//net",
+ ]
+
+ sources = [ "cronet_global_state_stubs.cc" ]
+
+ if (is_mac && !is_component_build) {
+ ldflags = [
+ "-install_name",
+ "@executable_path/$_cronet_shared_lib_file_name",
+ ]
+ public_configs = [ ":shared_library_public_config" ]
+ }
+ }
+
+ test("cronet_tests") {
+ deps = [
+ ":cronet_common",
+ "//base",
+ "//base/test:test_support",
+ "//components/cronet/native:cronet_native_impl",
+ "//components/cronet/native/test:cronet_native_tests",
+ "//net",
+ ]
+
+ sources = [
+ "cronet_global_state_stubs.cc",
+ "run_all_unittests.cc",
+ ]
+
+ defines = [ "CRONET_TESTS_IMPLEMENTATION" ]
+
+ if ((is_linux || is_chromeos) && !is_component_build) {
+ public_configs = [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
+ }
+
+ if (is_fuchsia) {
+ use_cfv2 = false
+ additional_manifest_fragments =
+ [ "//build/config/fuchsia/test/network_capabilities.test-cmx" ]
+ }
+ }
+
+ test("cronet_unittests") {
+ deps = [
+ ":cronet_common",
+ ":cronet_common_unittests",
+ "//base",
+ "//base/test:test_support",
+ "//components/cronet/native:cronet_native_unittests",
+ "//net",
+ ]
+
+ sources = [
+ "cronet_global_state_stubs.cc",
+ "run_all_unittests.cc",
+ ]
+ }
+
+ _package_dir = "$root_out_dir/cronet"
+
+ # Generate LICENSE file by recursively joining all dependent licenses.
+ action("generate_license") {
+ _license_path = "$_package_dir/LICENSE"
+
+ script = "//tools/licenses.py"
+ inputs = [ lastchange_file ]
+ outputs = [ _license_path ]
+ args = [
+ "license_file",
+ rebase_path(_license_path, root_build_dir),
+ "--gn-target",
+ "//components/cronet:cronet",
+ "--gn-out-dir",
+ ".",
+ ]
+ }
+
+ # Copy boiler-plate files into the package.
+ copy("cronet_package_copy") {
+ sources = [
+ "${root_out_dir}${shlib_subdir}/${_cronet_shared_lib_file_name}",
+ "//AUTHORS",
+ "//chrome/VERSION",
+ ]
+ deps = [ ":cronet" ]
+ outputs = [ "$_package_dir/{{source_file_part}}" ]
+ }
+
+ # Copy headers.
+ copy("cronet_package_headers") {
+ sources = cronet_native_public_headers + grpc_public_headers
+
+ outputs = [ "$_package_dir/include/{{source_file_part}}" ]
+ }
+
+ group("cronet_package") {
+ deps = [
+ ":cronet_package_copy",
+ ":cronet_package_headers",
+ ":generate_license",
+ ]
+ }
+
+ executable("cronet_native_perf_test") {
+ testonly = true
+ sources = [
+ "native/perftest/main.cc",
+ "native/perftest/perf_test.cc",
+ ]
+ deps = [
+ "//base",
+ "//components/cronet",
+ "//components/cronet/native:cronet_native_headers",
+ "//components/cronet/native/test:cronet_native_tests",
+ "//components/cronet/native/test:cronet_native_testutil",
+ "//net:test_support",
+ ]
+ }
+
+ executable("cronet_sample") {
+ testonly = true
+ sources = [
+ "native/sample/main.cc",
+ "native/sample/sample_executor.cc",
+ "native/sample/sample_executor.h",
+ "native/sample/sample_url_request_callback.cc",
+ "native/sample/sample_url_request_callback.h",
+ ]
+ deps = [
+ "//components/cronet",
+ "//components/cronet/native:cronet_native_headers",
+ ]
+ if ((is_linux || is_chromeos) && !is_component_build) {
+ public_configs = [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
+ }
+ }
+
+ test("cronet_sample_test") {
+ sources = [ "native/sample/test/sample_test.cc" ]
+ deps = [
+ ":cronet_sample",
+ "//testing/gtest:gtest",
+ ]
+ }
+}
diff --git a/src/components/cronet/DEPS b/src/components/cronet/DEPS
new file mode 100644
index 0000000000..9b584a17ac
--- /dev/null
+++ b/src/components/cronet/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+ "+components/grpc_support",
+ "+components/metrics",
+ "+components/prefs",
+ "+net",
+ "+third_party/metrics_proto",
+ "+third_party/zlib",
+]
diff --git a/src/components/cronet/DIR_METADATA b/src/components/cronet/DIR_METADATA
new file mode 100644
index 0000000000..9e5f77e85f
--- /dev/null
+++ b/src/components/cronet/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+ component: "Internals>Network>Library"
+}
+
+team_email: "net-dev@chromium.org"
diff --git a/src/components/cronet/OWNERS b/src/components/cronet/OWNERS
new file mode 100644
index 0000000000..ace4d683a7
--- /dev/null
+++ b/src/components/cronet/OWNERS
@@ -0,0 +1,5 @@
+cleborgne@google.com
+danstahr@google.com
+sporeba@google.com
+torne@chromium.org
+file://net/OWNERS
diff --git a/src/components/cronet/PRESUBMIT.py b/src/components/cronet/PRESUBMIT.py
new file mode 100644
index 0000000000..62f1fc4722
--- /dev/null
+++ b/src/components/cronet/PRESUBMIT.py
@@ -0,0 +1,106 @@
+# 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.
+
+"""Top-level presubmit script for src/components/cronet.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+import os
+
+USE_PYTHON3 = True
+
+
+def _PyLintChecks(input_api, output_api):
+ pylint_checks = input_api.canned_checks.GetPylint(input_api, output_api,
+ extra_paths_list=_GetPathsToPrepend(input_api), pylintrc='pylintrc')
+ return input_api.RunTests(pylint_checks)
+
+
+def _GetPathsToPrepend(input_api):
+ current_dir = input_api.PresubmitLocalPath()
+ chromium_src_dir = input_api.os_path.join(current_dir, '..', '..')
+ return [
+ input_api.os_path.join(chromium_src_dir, 'components'),
+ input_api.os_path.join(chromium_src_dir, 'tools', 'perf'),
+ input_api.os_path.join(chromium_src_dir, 'build', 'android'),
+ input_api.os_path.join(chromium_src_dir, 'build', 'android', 'gyp'),
+ input_api.os_path.join(chromium_src_dir,
+ 'mojo', 'public', 'tools', 'bindings', 'pylib'),
+ input_api.os_path.join(chromium_src_dir, 'net', 'tools', 'net_docs'),
+ input_api.os_path.join(chromium_src_dir, 'tools'),
+ input_api.os_path.join(chromium_src_dir, 'third_party'),
+ input_api.os_path.join(chromium_src_dir,
+ 'third_party', 'catapult', 'telemetry'),
+ input_api.os_path.join(chromium_src_dir,
+ 'third_party', 'catapult', 'devil'),
+ input_api.os_path.join(chromium_src_dir,
+ 'third_party', 'catapult', 'common', 'py_utils'),
+ ]
+
+
+def _PackageChecks(input_api, output_api):
+ """Verify API classes are in org.chromium.net package, and implementation
+ classes are not in org.chromium.net package."""
+ api_file_pattern = input_api.re.compile(
+ r'^components/cronet/android/api/.*\.(java|template)$')
+ impl_file_pattern = input_api.re.compile(
+ r'^components/cronet/android/java/.*\.(java|template)$')
+ api_package_pattern = input_api.re.compile(r'^package (?!org.chromium.net;)')
+ impl_package_pattern = input_api.re.compile(r'^package org.chromium.net;')
+
+ source_filter = lambda path: input_api.FilterSourceFile(path,
+ files_to_check=[r'^components/cronet/android/.*\.(java|template)$'])
+
+ problems = []
+ for f in input_api.AffectedSourceFiles(source_filter):
+ local_path = f.LocalPath()
+ for line_number, line in f.ChangedContents():
+ if (api_file_pattern.search(local_path)):
+ if (api_package_pattern.search(line)):
+ problems.append(
+ '%s:%d\n %s' % (local_path, line_number, line.strip()))
+ elif (impl_file_pattern.search(local_path)):
+ if (impl_package_pattern.search(line)):
+ problems.append(
+ '%s:%d\n %s' % (local_path, line_number, line.strip()))
+
+ if problems:
+ return [output_api.PresubmitError(
+ 'API classes must be in org.chromium.net package, and implementation\n'
+ 'classes must not be in org.chromium.net package.',
+ problems)]
+ else:
+ return []
+
+
+def _RunToolsUnittests(input_api, output_api):
+ return input_api.canned_checks.RunUnitTestsInDirectory(
+ input_api, output_api,
+ '.',
+ [ r'^tools_unittest\.py$'],
+ run_on_python3=True)
+
+
+def _ChangeAffectsCronetTools(change):
+ """ Returns |true| if the change may affect Cronet tools. """
+
+ for path in change.LocalPaths():
+ if path.startswith(os.path.join('components', 'cronet', 'tools')):
+ return True
+ return False
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ results = []
+ results.extend(_PyLintChecks(input_api, output_api))
+ results.extend(_PackageChecks(input_api, output_api))
+ if _ChangeAffectsCronetTools(input_api.change):
+ results.extend(_RunToolsUnittests(input_api, output_api))
+ return results
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return _RunToolsUnittests(input_api, output_api)
diff --git a/src/components/cronet/README.md b/src/components/cronet/README.md
new file mode 100644
index 0000000000..dfd428389d
--- /dev/null
+++ b/src/components/cronet/README.md
@@ -0,0 +1,176 @@
+# Quick Start Guide to Using Cronet
+Cronet is the networking stack of Chromium put into a library for use on
+mobile. This is the same networking stack that is used in the Chrome browser
+by over a billion people. It offers an easy-to-use, high performance,
+standards-compliant, and secure way to perform HTTP requests. Cronet has support
+for both Android and iOS. On Android, Cronet offers its own Java asynchronous
+API as well as support for the [java.net.HttpURLConnection] API.
+This document gives a brief introduction to using these two Java APIs.
+
+For instructions on checking out and building Cronet see
+[Cronet build instructions](build_instructions.md).
+
+Testing information is available on the [native
+API](native/test_instructions.md) and [Android
+API](android/test_instructions.md) pages.
+
+### Basics
+First you will need to extend `UrlRequest.Callback` to handle
+events during the lifetime of a request. For example:
+
+ class MyCallback extends UrlRequest.Callback {
+ @Override
+ public void onRedirectReceived(UrlRequest request,
+ UrlResponseInfo responseInfo, String newLocationUrl) {
+ if (followRedirect) {
+ // Let's tell Cronet to follow the redirect!
+ request.followRedirect();
+ } else {
+ // Not worth following the redirect? Abandon the request.
+ request.cancel();
+ }
+ }
+
+ @Override
+ public void onResponseStarted(UrlRequest request,
+ UrlResponseInfo responseInfo) {
+ // Now we have response headers!
+ int httpStatusCode = responseInfo.getHttpStatusCode();
+ if (httpStatusCode == 200) {
+ // Success! Let's tell Cronet to read the response body.
+ request.read(myBuffer);
+ } else if (httpStatusCode == 503) {
+ // Do something. Note that 4XX and 5XX are not considered
+ // errors from Cronet's perspective since the response is
+ // successfully read.
+ }
+ mResponseHeaders = responseInfo.getAllHeaders();
+ }
+
+ @Override
+ public void onReadCompleted(UrlRequest request,
+ UrlResponseInfo responseInfo, ByteBuffer byteBuffer) {
+ // Response body is available.
+ doSomethingWithResponseData(byteBuffer);
+ // Let's tell Cronet to continue reading the response body or
+ // inform us that the response is complete!
+ request.read(mBuffer);
+ }
+
+ @Override
+ public void onSucceeded(UrlRequest request,
+ UrlResponseInfo responseInfo) {
+ // Request has completed successfully!
+ }
+
+ @Override
+ public void onFailed(UrlRequest request,
+ UrlResponseInfo responseInfo, CronetException error) {
+ // Request has failed. responseInfo might be null.
+ Log.e("MyCallback", "Request failed. " + error.getMessage());
+ // Maybe handle error here. Typical errors include hostname
+ // not resolved, connection to server refused, etc.
+ }
+ }
+
+Make a request like this:
+
+ CronetEngine.Builder engineBuilder = new CronetEngine.Builder(getContext());
+ CronetEngine engine = engineBuilder.build();
+ Executor executor = Executors.newSingleThreadExecutor();
+ MyCallback callback = new MyCallback();
+ UrlRequest.Builder requestBuilder = engine.newUrlRequestBuilder(
+ "https://www.example.com", callback, executor);
+ UrlRequest request = requestBuilder.build();
+ request.start();
+
+In the above example, `MyCallback` extends `UrlRequest.Callback`. The request
+is started asynchronously. When the response is ready (fully or partially), and
+in the event of failures or redirects, `callback`'s methods will be invoked on
+`executor`'s thread to inform the client of the request state and/or response
+information.
+
+### Downloading Data
+When Cronet fetches response headers from the server or gets them from the
+cache, `UrlRequest.Callback.onResponseStarted` will be invoked. To read the
+response body, the client should call `UrlRequest.read` and supply a
+[ByteBuffer] for Cronet to fill. Once a portion or all of
+the response body is read, `UrlRequest.Callback.onReadCompleted` will be invoked.
+The client may then read and consume the data within `byteBuffer`.
+Once the client is ready to consume more data, the client should call
+`UrlRequest.read` again. The process continues until
+`UrlRequest.Callback.onSucceeded` or `UrlRequest.Callback.onFailed` is invoked,
+which signals the completion of the request.
+
+### Uploading Data
+ MyUploadDataProvider myUploadDataProvider = new MyUploadDataProvider();
+ requestBuilder.setHttpMethod("POST");
+ requestBuilder.setUploadDataProvider(myUploadDataProvider, executor);
+
+In the above example, `MyUploadDataProvider` extends `UploadDataProvider`.
+When Cronet is ready to send the request body,
+`myUploadDataProvider.read(UploadDataSink uploadDataSink,
+ByteBuffer byteBuffer)` will be invoked. The client will need to write the
+request body into `byteBuffer`. Once the client is done writing into
+`byteBuffer`, the client can let Cronet know by calling
+`uploadDataSink.onReadSucceeded`. If the request body doesn't fit into
+`byteBuffer`, the client can continue writing when `UploadDataProvider.read` is
+invoked again. For more details, please see the API reference.
+
+### Configuring Cronet
+Various configuration options are available via the `CronetEngine.Builder`
+object.
+
+Enabling HTTP/2 and QUIC:
+
+- For Example:
+
+ engineBuilder.enableHttp2(true).enableQuic(true);
+
+Controlling the cache:
+
+- Use a 100KiB in-memory cache:
+
+ engineBuilder.enableHttpCache(
+ CronetEngine.Builder.HttpCache.IN_MEMORY, 100 * 1024);
+
+- or use a 1MiB disk cache:
+
+ engineBuilder.setStoragePath(storagePathString);
+ engineBuilder.enableHttpCache(CronetEngine.Builder.HttpCache.DISK,
+ 1024 * 1024);
+
+### Debugging
+To get more information about how Cronet is processing network
+requests, you can start and stop **NetLog** logging by calling
+`CronetEngine.startNetLogToFile` and `CronetEngine.stopNetLog`.
+Bear in mind that logs may contain sensitive data. You may analyze the
+generated log by navigating to [chrome://net-internals#import] using a
+Chrome browser.
+
+# Using the java.net.HttpURLConnection API
+Cronet offers an implementation of the [java.net.HttpURLConnection] API to make
+it easier for apps which rely on this API to use Cronet.
+To open individual connections using Cronet's implementation, do the following:
+
+ HttpURLConnection connection =
+ (HttpURLConnection)engine.openConnection(url);
+
+To use Cronet's implementation instead of the system's default implementation
+for all connections established using `URL.openConnection()` do the following:
+
+ URL.setURLStreamHandlerFactory(engine.createURLStreamHandlerFactory());
+
+Cronet's
+HttpURLConnection implementation has some limitations as compared to the system
+implementation, including not utilizing the default system HTTP cache (Please
+see {@link org.chromium.net.CronetEngine#createURLStreamHandlerFactory} for
+more information).
+You can configure Cronet and control caching through the
+`CronetEngine.Builder` instance, `engineBuilder`
+(See [Configuring Cronet](#configuring-cronet) section), before you build the
+`CronetEngine` and then call `CronetEngine.createURLStreamHandlerFactory()`.
+
+[ByteBuffer]: https://developer.android.com/reference/java/nio/ByteBuffer.html
+[chrome://net-internals#import]: chrome://net-internals#import
+[java.net.HttpURLConnection]: https://developer.android.com/reference/java/net/HttpURLConnection.html
diff --git a/src/components/cronet/__init__.py b/src/components/cronet/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/components/cronet/android/BUILD.gn b/src/components/cronet/android/BUILD.gn
new file mode 100644
index 0000000000..a60928d5d2
--- /dev/null
+++ b/src/components/cronet/android/BUILD.gn
@@ -0,0 +1,1582 @@
+# 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("//build/android/resource_sizes.gni")
+import("//build/buildflag_header.gni")
+import("//build/config/android/config.gni")
+import("//build/config/android/rules.gni")
+import("//build/config/zip.gni")
+import("//build/util/lastchange.gni")
+import("//build/util/process_version.gni")
+import("//build/util/version.gni")
+import("//components/cronet/native/include/headers.gni")
+import("//components/grpc_support/include/headers.gni")
+import("//testing/test.gni")
+import("//third_party/netty4/netty4.gni")
+import("//third_party/protobuf/proto_library.gni")
+import("//tools/binary_size/sizes.gni")
+import("//url/features.gni")
+
+_jni_registration_header = "$target_gen_dir/cronet_jni_registration.h"
+_templates_dir = "$target_gen_dir/templates"
+
+declare_args() {
+ # In integrated mode, CronetEngine will use the shared network task runner by
+ # other Chromium-based clients like webview without self-initialization.
+ # Besides, the native library would be compiled and loaded together with the
+ # native library of host. This mode is only for Android.
+ integrated_mode = false
+}
+
+buildflag_header("buildflags") {
+ header = "buildflags.h"
+ flags = [ "INTEGRATED_MODE=$integrated_mode" ]
+}
+
+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",
+ ]
+}
+
+generate_jni_registration("cronet_jni_registration") {
+ targets = [ ":cronet_impl_native_base_java" ]
+ header_output = _jni_registration_header
+ sources_exclusions = [
+ "//base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
+ "//base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java",
+ "//base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java",
+ "//base/android/java/src/org/chromium/base/SysUtils.java",
+ ]
+}
+
+android_library("cronet_jni_registration_java") {
+ srcjar_deps = [ ":cronet_jni_registration" ]
+}
+
+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("net_idempotency_java") {
+ sources = [ "//net/base/idempotency.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" ]
+}
+
+java_cpp_template("integrated_mode_state") {
+ sources = [ "java/src/org/chromium/net/impl/IntegratedModeState.template" ]
+ if (integrated_mode) {
+ defines = [ "INTEGRATED_MODE" ]
+ }
+}
+
+_generated_api_version_java = "$_templates_dir/org/chromium/net/ApiVersion.java"
+_api_level = read_file("api_version.txt", "value")
+
+process_version("api_version") {
+ process_only = true
+ template_file = "api/src/org/chromium/net/ApiVersion.template"
+ sources = [
+ "//chrome/VERSION",
+ lastchange_file,
+ ]
+ extra_args = [
+ "-e",
+ "API_LEVEL=$_api_level",
+ ]
+ output = _generated_api_version_java
+}
+
+_generated_impl_version_java =
+ "$_templates_dir/org/chromium/net/impl/ImplVersion.java"
+
+process_version("impl_version") {
+ process_only = true
+ template_file = "java/src/org/chromium/net/impl/ImplVersion.template"
+ sources = [
+ "//chrome/VERSION",
+ lastchange_file,
+ ]
+ extra_args = [
+ "-e",
+ "API_LEVEL=$_api_level",
+ ]
+ output = _generated_impl_version_java
+}
+
+_cronet_version_header_include_dir = "$target_gen_dir/cronet_version_header"
+
+source_set("cronet_static") {
+ deps = [
+ ":buildflags",
+ ":cronet_jni_headers",
+ ":cronet_jni_registration",
+ "//base",
+ "//base/third_party/dynamic_annotations",
+ "//components/cronet:cronet_common",
+ "//components/cronet:cronet_version_header",
+ "//components/cronet:metrics_util",
+ "//components/cronet/native:cronet_native_impl",
+ "//components/metrics",
+ "//components/prefs",
+ "//net",
+ "//third_party/zlib:zlib",
+ "//url",
+ "//url:buildflags",
+ ]
+ 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_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/url_request_error.cc",
+ "//components/cronet/android/url_request_error.h",
+ _jni_registration_header,
+ ]
+
+ if (integrated_mode) {
+ sources += [
+ "//components/cronet/android/cronet_integrated_mode_state.cc",
+ "//components/cronet/android/cronet_integrated_mode_state.h",
+ ]
+ } else {
+ sources += [ "//components/cronet/android/cronet_library_loader.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("android_only_jni_onload_and_cronet_exports.lst",
+ root_out_dir) ]
+}
+
+_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" ]
+}
+
+sizes_test("cronet_sizes") {
+ data_deps = [ ":cronet" ]
+ data = [ "${root_out_dir}/lib${_cronet_shared_lib_name}.so" ]
+ executable_args = [
+ "--platform",
+ "android-cronet",
+ ]
+}
+
+# cronet_api_java.jar defines Cronet API.
+android_library("cronet_api_java") {
+ sources = [
+ "api/src/org/chromium/net/BidirectionalStream.java",
+ "api/src/org/chromium/net/CallbackException.java",
+ "api/src/org/chromium/net/CronetEngine.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",
+ _generated_api_version_java,
+ ]
+
+ deps = [
+ ":api_version",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+}
+
+cronet_impl_common_java_srcjar_deps = [
+ ":http_cache_type_java",
+ ":integrated_mode_state",
+ ":load_states_list",
+ ":rtt_throughput_values_java",
+ "//net:effective_connection_type_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") {
+ sources = [
+ "java/src/org/chromium/net/impl/CallbackExceptionImpl.java",
+ "java/src/org/chromium/net/impl/CronetEngineBase.java",
+ "java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java",
+ "java/src/org/chromium/net/impl/CronetExceptionImpl.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",
+ _generated_impl_version_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",
+ ":impl_version",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+ deps += cronet_impl_common_java_deps_to_package
+
+ srcjar_deps = cronet_impl_common_java_srcjar_deps
+}
+
+# cronet_impl_java_util_java.jar - Classes shared between Java Cronet implementations.
+android_library("cronet_impl_java_util_java") {
+ sources = [
+ "java/src/org/chromium/net/impl/JavaUploadDataSinkBase.java",
+ "java/src/org/chromium/net/impl/JavaUrlRequestUtils.java",
+ ]
+
+ deps = [
+ ":cronet_api_java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+}
+
+# cronet_impl_platform_base_java.jar - Java platform based implementation of the Cronet engine.
+android_library("cronet_impl_platform_base_java") {
+ sources = [
+ "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",
+ ":cronet_impl_java_util_java",
+ "//net/android:net_thread_stats_uid_java",
+ "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+}
+
+# cronet_impl_fake_base_java.jar - Fake implementation of Cronet.
+android_library("cronet_impl_fake_base_java") {
+ sources = [
+ "fake/java/org/chromium/net/test/FakeCronetController.java",
+ "fake/java/org/chromium/net/test/FakeCronetEngine.java",
+ "fake/java/org/chromium/net/test/FakeCronetProvider.java",
+ "fake/java/org/chromium/net/test/FakeUrlRequest.java",
+ "fake/java/org/chromium/net/test/FakeUrlResponse.java",
+ "fake/java/org/chromium/net/test/ResponseMatcher.java",
+ "fake/java/org/chromium/net/test/UrlResponseMatcher.java",
+ ]
+
+ deps = [
+ ":cronet_api_java",
+ ":cronet_impl_common_base_java",
+ ":cronet_impl_java_util_java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+}
+
+cronet_impl_native_java_srcjar_deps = [
+ ":net_idempotency_java",
+ ":net_request_priority_java",
+ ":network_quality_observation_source_java",
+ ":url_request_error_java",
+]
+
+cronet_impl_native_java_deps_to_package = [
+ ":cronet_urlconnection_impl_java",
+ "//base:base_java",
+ "//base:jni_java",
+ "//build/android:build_config_java",
+ "//net/android:net_java",
+ "//url:url_java",
+]
+
+android_library("cronet_urlconnection_impl_java") {
+ sources = [
+ "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",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+}
+
+# cronet_impl_native_base_java.jar - native implementation of the Cronet engine.
+android_library("cronet_impl_native_base_java") {
+ sources = [
+ "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",
+ "//base:jni_java",
+ "//build/android:build_config_java",
+ "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+ deps += cronet_impl_native_java_deps_to_package
+ annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+
+ 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",
+ ]
+}
+
+android_resources("cronet_sample_apk_resources") {
+ sources = [
+ "sample/res/layout/activity_main.xml",
+ "sample/res/layout/dialog_url.xml",
+ "sample/res/values/dimens.xml",
+ "sample/res/values/strings.xml",
+ ]
+ android_manifest = "sample/AndroidManifest.xml"
+ deps = [ "//third_party/android_deps:android_support_v7_appcompat_java" ]
+}
+
+android_library("cronet_sample_apk_java") {
+ sources = [
+ "sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java",
+ "sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java",
+ ]
+
+ resources_package = "org.chromium.cronet_sample_apk"
+ deps = [
+ ":cronet_sample_apk_resources",
+ ":package_api_java",
+ ":package_impl_native_java",
+ "//third_party/android_deps:android_support_v7_appcompat_java",
+ "//third_party/androidx:androidx_annotation_annotation_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
+
+ enable_multidex = false
+ if (!is_java_debug) {
+ proguard_enabled = true
+ proguard_configs = [
+ "$target_gen_dir/cronet_impl_native_proguard.cfg",
+ "cronet_impl_common_proguard.cfg",
+ "//base/android/proguard/chromium_apk.flags",
+ ]
+ }
+}
+
+android_resource_sizes_test("resource_sizes_cronet_sample_apk") {
+ apk_name = "CronetSample"
+ data_deps = [ ":cronet_sample_apk" ]
+}
+
+action("cronet_combine_proguard_flags") {
+ script = "//components/cronet/tools/generate_proguard_file.py"
+ sources = [
+ "//base/android/proguard/chromium_code.flags",
+
+ # Massage the proguard to avoid incompatibilities when building internally.
+ "//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 = [ ":repackage_api" ]
+}
+
+android_java_prebuilt("package_impl_common_java") {
+ jar_path = "$_package_dir/cronet_impl_common_java.jar"
+ deps = [
+ ":package_api_java",
+ ":repackage_common",
+ ]
+}
+
+java_prebuilt("package_impl_native_java") {
+ # This target is a java_prebuilt instead of a android_java_prebuilt so we
+ # don't filter out GEN_JNI which is part of jar_excluded_patterns in
+ # android_java_prebuilt.
+ jar_path = "$_package_dir/cronet_impl_native_java.jar"
+ supports_android = true
+ requires_android = true
+ deps = [
+ ":package_api_java",
+ ":package_impl_common_java",
+ ":repackage_native",
+ "//third_party/android_deps:android_support_v4_java",
+ "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
+ ]
+ jar_excluded_patterns = [ "androidx/*/R*" ]
+}
+
+android_java_prebuilt("package_impl_util_java") {
+ jar_path = "$_package_dir/cronet_impl_util_java.jar"
+ deps = [
+ ":package_api_java",
+ ":repackage_util",
+ ]
+}
+
+android_java_prebuilt("package_impl_platform_java") {
+ jar_path = "$_package_dir/cronet_impl_platform_java.jar"
+ deps = [
+ ":package_api_java",
+ ":package_impl_common_java",
+ ":repackage_platform",
+ ]
+}
+
+android_java_prebuilt("package_impl_fake_java") {
+ jar_path = "$_package_dir/cronet_impl_fake_java.jar"
+ deps = [
+ ":package_api_java",
+ ":package_impl_common_java",
+ ":repackage_fake",
+ ]
+}
+
+template("jar_src") {
+ action_with_pydeps(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",
+ _templates_dir,
+ ]
+ source_deps = [ ":cronet_api_java" ]
+ jar_path = "$_package_dir/cronet_api-src.jar"
+}
+
+jar_src("jar_cronet_impl_common_java_source") {
+ src_search_dirs = [
+ "java/src",
+ _templates_dir,
+ ]
+ 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"
+}
+
+jar_src("jar_cronet_impl_fake_java_source") {
+ src_search_dirs = [ "fake/java" ]
+ source_deps = [ ":cronet_impl_fake_base_java" ]
+ jar_path = "$_package_dir/cronet_impl_fake_java-src.jar"
+}
+
+jar_src("jar_cronet_impl_util_java_source") {
+ src_search_dirs = [ "java/src" ]
+ source_deps = [ ":cronet_impl_java_util_java" ]
+ jar_path = "$_package_dir/cronet_impl_util_java-src.jar"
+}
+
+# List of patterns of .class files to exclude from the jar.
+_jar_excluded_patterns = [
+ # Excludes Android support libraries crbug.com/832770.
+ "android/*",
+ "androidx/*",
+ "*/library_loader/*.class",
+ "*/multidex/*.class",
+ "*/process_launcher/*.class",
+ "*/SysUtils*.class",
+ "org/chromium/base/FeatureList*.class",
+ "org/chromium/base/jank_tracker/*.class",
+ "org/chromium/base/memory/MemoryPressureMonitor*.class",
+]
+
+template("repackage_jars") {
+ dist_jar(target_name) {
+ requires_android = true
+ direct_deps_only = true
+ use_unprocessed_jars = true
+ no_build_hooks = true
+ forward_variables_from(invoker, "*")
+ }
+}
+
+repackage_jars("repackage_api") {
+ output = "$_package_dir/cronet_api.jar"
+ deps = [ ":cronet_api_java" ]
+}
+
+repackage_jars("repackage_platform") {
+ output = "$_package_dir/cronet_impl_platform_java.jar"
+ deps = [ ":cronet_impl_platform_base_java" ]
+}
+
+repackage_jars("repackage_fake") {
+ output = "$_package_dir/cronet_impl_fake_java.jar"
+ deps = [ ":cronet_impl_fake_base_java" ]
+}
+
+repackage_jars("repackage_util") {
+ output = "$_package_dir/cronet_impl_util_java.jar"
+ deps = [ ":cronet_impl_java_util_java" ]
+}
+
+# See crbug.com/1005836 for more info on why repackage_native requires 2 extra
+# targets. These 3 targets exist to ensure the correct version of GEN_JNI
+# (a generated class containing native method definitions) is included.
+repackage_jars("repackage_native") {
+ output = "$_package_dir/cronet_impl_native_java.jar"
+ deps = [
+ ":cronet_jni_registration_java",
+ ":repackage_native_java",
+ ]
+ jar_excluded_patterns = _jar_excluded_patterns
+}
+
+_native_intermediate_jar_path = "$target_out_dir/repackage_native_impl.jar"
+
+# Do not depend on this target directly. Use :repackage_native.
+repackage_jars("repackage_native_impl") {
+ output = _native_intermediate_jar_path
+ deps = cronet_impl_native_java_deps_to_package +
+ [ ":cronet_impl_native_base_java" ]
+ jar_excluded_patterns = _jar_excluded_patterns
+}
+
+# Do not depend on this target directly. Use :repackage_native.
+# This target exists to provide :repackage_native with a suitable target to
+# depend on (since dist_aar only pulls in deps of type "java_library").
+android_java_prebuilt("repackage_native_java") {
+ jar_path = _native_intermediate_jar_path
+
+ # Since only the unprocessed jar is used, no need to complete the bytecode
+ # processing step.
+ enable_bytecode_checks = false
+ deps = [ ":repackage_native_impl" ]
+}
+
+repackage_jars("repackage_common") {
+ output = "$_package_dir/cronet_impl_common_java.jar"
+ deps = cronet_impl_common_java_deps_to_package + [
+ ":cronet_impl_common_base_java",
+ ":cronet_impl_java_util_java",
+ ]
+}
+
+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") {
+ sources = [
+ "sample/res/layout/activity_main.xml",
+ "sample/res/layout/dialog_url.xml",
+ "sample/res/values/dimens.xml",
+ "sample/res/values/strings.xml",
+ ]
+ 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"
+ sources = [ "sample/javatests/src/org/chromium/cronet_sample_apk/CronetSampleTest.java" ]
+ deps = [
+ ":cronet_sample_apk_java",
+ "//third_party/android_deps:espresso_java",
+ "//third_party/android_support_test_runner:rules_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/androidx:androidx_test_runner_java",
+ "//third_party/junit",
+ ]
+
+ enable_multidex = false
+ if (!is_java_debug) {
+ 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",
+ ]
+ }
+
+ 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",
+ "test/url_request_intercepting_job_factory.cc",
+ "test/url_request_intercepting_job_factory.h",
+ ]
+
+ deps = [
+ ":cronet",
+ ":cronet_tests_jni_headers",
+ "//base",
+ "//base:i18n",
+ "//base/test:test_support",
+ "//components/cronet:cronet_version_header",
+ "//components/cronet/testing: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
+ sources = [
+ "test/res/values/strings.xml",
+ "test/res/xml/network_security_config.xml",
+ "test/smoketests/res/native/values/strings.xml",
+ ]
+ }
+
+ android_library("cronet_test_apk_java") {
+ testonly = true
+
+ sources = [
+ "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/ReportingCollector.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/android_sdk:android_test_base_java",
+ "//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",
+ ]
+
+ # cronet_common_javatests.jar - Cronet Java test common files.
+ android_library("cronet_common_javatests") {
+ testonly = true
+ sources = [
+ "test/javatests/src/org/chromium/net/CronetTestRule.java",
+ "test/javatests/src/org/chromium/net/TestUploadDataProvider.java",
+ "test/javatests/src/org/chromium/net/TestUrlRequestCallback.java",
+ ]
+ deps = [
+ ":cronet_api_java",
+ ":cronet_impl_all_java",
+ "//base:base_java",
+ "//third_party/android_sdk:android_test_base_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/junit",
+ ]
+ }
+
+ # cronet_fake_javatests.jar - Java tests for the fake implementation of Cronet.
+ android_library("cronet_fake_javatests") {
+ testonly = true
+ sources = [
+ "fake/javatests/org/chromium/net/test/FakeCronetControllerTest.java",
+ "fake/javatests/org/chromium/net/test/FakeCronetEngineTest.java",
+ "fake/javatests/org/chromium/net/test/FakeCronetProviderTest.java",
+ "fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java",
+ "fake/javatests/org/chromium/net/test/FakeUrlResponseTest.java",
+ "fake/javatests/org/chromium/net/test/UrlResponseMatcherTest.java",
+ ]
+
+ deps = [
+ ":cronet_api_java",
+ ":cronet_common_javatests",
+ ":cronet_impl_common_base_java",
+ ":cronet_impl_fake_base_java",
+ ":cronet_impl_platform_base_java",
+ "//base:base_java_test_support",
+ "//third_party/android_sdk:android_test_base_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/androidx:androidx_test_runner_java",
+ "//third_party/junit",
+ "//third_party/mockito:mockito_java",
+ ]
+ }
+
+ cronet_javatests_deps_to_package = [
+ ":cronet_common_javatests",
+ ":cronet_fake_javatests",
+ ":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
+
+ sources = [
+ "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/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/NQETest.java",
+ "test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java",
+ "test/javatests/src/org/chromium/net/NetworkErrorLoggingTest.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/UploadDataProvidersTest.java",
+ "test/javatests/src/org/chromium/net/UrlResponseInfoTest.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/CronetInputStreamTest.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",
+ ]
+
+ # 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",
+ ":cronet_urlconnection_impl_java",
+ "//third_party/android_sdk:android_test_base_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/androidx:androidx_test_runner_java",
+ "//third_party/google-truth:google_truth_java",
+ "//third_party/hamcrest:hamcrest_core_java",
+ "//third_party/junit",
+ "//third_party/mockito:mockito_java",
+ ]
+ deps += cronet_javatests_deps_to_package
+ data = [ "//components/cronet/testing/test_server/data/" ]
+ }
+
+ instrumentation_test_apk("cronet_test_instrumentation_apk") {
+ # This is the only Cronet APK with lint enabled. This one was chosen because
+ # it depends on basically all source files.
+ enable_lint = true
+ lint_suppressions_file = "lint-suppressions.xml"
+ lint_baseline_file = "lint-baseline.xml"
+
+ # Still needs to support KitKat. See crbug.com/1042122.
+ lint_min_sdk_version = 19
+
+ apk_name = "CronetTestInstrumentation"
+ android_manifest = "test/javatests/AndroidManifest.xml"
+
+ shared_libraries = [
+ ":cronet",
+ ":cronet_tests",
+ ]
+ loadable_modules = [ "$root_out_dir/libnetty-tcnative.so" ]
+
+ sources = cronet_smoketests_native_common_srcs + [
+ "test/smoketests/src/org/chromium/net/smoke/Http2Test.java",
+ "test/smoketests/src/org/chromium/net/smoke/QuicTest.java",
+ ]
+
+ deps = [
+ ":cronet_api_java",
+ ":cronet_combine_proguard_flags",
+ ":cronet_impl_all_java",
+ ":cronet_javatests",
+ ":cronet_test_apk_java",
+ ":cronet_test_apk_resources",
+ "//base:base_java",
+ "//base:base_java_test_support",
+ "//net/android:net_java",
+ "//net/android:net_java_test_support",
+ "//third_party/android_sdk:android_test_base_java",
+ "//third_party/android_sdk:android_test_mock_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/androidx:androidx_test_runner_java",
+ "//third_party/hamcrest:hamcrest_core_java",
+ "//third_party/junit",
+ "//third_party/netty-tcnative:netty-tcnative-so",
+ "//third_party/netty4:netty_all_java",
+ ]
+ additional_apks = [ "//net/android:net_test_support_apk" ]
+
+ data_deps = [ "//net:test_support" ]
+
+ enable_multidex = true
+ if (!is_java_debug) {
+ proguard_enabled = true
+
+ proguard_configs = [
+ "$target_gen_dir/cronet_impl_native_proguard.cfg",
+ "cronet_impl_common_proguard.cfg",
+ "cronet_impl_platform_proguard.cfg",
+ "test/proguard.cfg",
+ ]
+ }
+ }
+
+ android_resources("cronet_smoketests_platform_only_apk_resources") {
+ testonly = true
+ sources = [
+ "test/smoketests/res/platform_only/values/strings.xml",
+ "test/smoketests/res/platform_only/xml/network_security_config.xml",
+ ]
+ }
+
+ instrumentation_test_apk(
+ "cronet_smoketests_platform_only_instrumentation_apk") {
+ apk_name = "PlatformOnlyEngineSmokeTestInstrumentation"
+ android_manifest = "test/javatests/AndroidManifest.xml"
+
+ sources = cronet_smoketests_platform_only_common_srcs + [
+ "test/src/org/chromium/net/CronetTestApplication.java",
+ "test/smoketests/src/org/chromium/net/smoke/PlatformOnlyEngineTest.java",
+ ]
+
+ deps = [
+ ":cronet_api_java",
+ ":cronet_impl_common_base_java",
+ ":cronet_impl_platform_base_java",
+ ":cronet_smoketests_platform_only_apk_resources",
+ "//base:base_java_test_support",
+ "//third_party/android_sdk:android_test_base_java",
+ "//third_party/android_sdk:android_test_mock_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/androidx:androidx_test_runner_java",
+ "//third_party/junit",
+ "//third_party/netty4:netty_all_java",
+ ]
+
+ if (!is_java_debug) {
+ proguard_enabled = true
+
+ proguard_configs = [
+ "cronet_impl_common_proguard.cfg",
+ "cronet_impl_platform_proguard.cfg",
+ "test/proguard.cfg",
+ ]
+ }
+ }
+
+ instrumentation_test_apk(
+ "cronet_smoketests_missing_native_library_instrumentation_apk") {
+ apk_name = "MissingNativeLibrarySmokeTestInstrumentation"
+ android_manifest = "test/javatests/AndroidManifest.xml"
+
+ sources = cronet_smoketests_native_common_srcs + [ "test/smoketests/src/org/chromium/net/smoke/MissingNativeLibraryTest.java" ]
+ deps = [
+ ":cronet_api_java",
+ ":cronet_combine_proguard_flags",
+ ":cronet_impl_common_base_java",
+ ":cronet_impl_platform_base_java",
+ ":cronet_test_apk_java",
+ ":cronet_test_apk_resources",
+ "//base:base_java",
+ "//base:base_java_test_support",
+ "//third_party/android_sdk:android_test_base_java",
+ "//third_party/android_sdk:android_test_mock_java",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/androidx:androidx_test_runner_java",
+ "//third_party/junit",
+ "//third_party/netty4:netty_all_java",
+ ]
+
+ enable_multidex = true
+ if (!is_java_debug) {
+ proguard_enabled = true
+ proguard_configs = [
+ "$target_gen_dir/cronet_impl_native_proguard.cfg",
+ "cronet_impl_common_proguard.cfg",
+ "cronet_impl_platform_proguard.cfg",
+ "test/proguard.cfg",
+ ]
+ }
+ }
+
+ android_apk("cronet_perf_test_apk") {
+ testonly = true
+ apk_name = "CronetPerfTest"
+ android_manifest = "test/javaperftests/AndroidManifest.xml"
+ shared_libraries = [
+ ":cronet",
+ ":cronet_tests",
+ ]
+
+ sources = [
+ "test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java",
+ ]
+
+ deps = [
+ ":cronet_api_java",
+ ":cronet_combine_proguard_flags",
+ ":cronet_impl_all_java",
+ ":cronet_javatests",
+ ":cronet_test_apk_java",
+ "//base:base_java",
+ "//third_party/android_sdk:android_test_mock_java",
+ "//third_party/junit",
+ ]
+
+ enable_multidex = true
+ if (!is_java_debug) {
+ 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",
+ "//testing/android/proguard_for_test.flags",
+ ]
+ enable_proguard_checks = false
+ }
+ }
+
+ 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/metrics",
+ "//components/prefs:test_support",
+ "//net",
+ "//net:test_support",
+ "//net/android:net_java",
+ "//testing/gtest",
+ ]
+
+ sources = [ "../run_all_unittests.cc" ]
+
+ data = [ "//components/cronet/testing/test_server/data/" ]
+
+ if (is_android) {
+ shard_timeout = 180
+ }
+ }
+
+ test("cronet_tests_android") {
+ deps = [
+ ":cronet_impl_native_base_java",
+ ":cronet_static",
+ "//base",
+ "//base/test:test_support",
+ "//components/cronet/native/test:cronet_native_tests",
+ "//components/metrics",
+ "//components/prefs:test_support",
+ "//net",
+ "//net:test_support",
+ "//net/android:net_java",
+ "//testing/gtest",
+ ]
+
+ allow_cleartext_traffic = true
+
+ sources = [ "../run_all_unittests.cc" ]
+
+ defines = [ "CRONET_TESTS_IMPLEMENTATION" ]
+
+ data = [ "//components/cronet/testing/test_server/data/" ]
+
+ if (is_android) {
+ shard_timeout = 180
+ }
+ }
+
+ _test_package_dir = "$root_out_dir/cronet/test"
+
+ repackage_jars("repackage_test_jars") {
+ output = "$_test_package_dir/cronet_tests_java.jar"
+ testonly = true
+ deps = cronet_javatests_deps_to_package + [
+ ":cronet_javatests",
+ "//third_party/netty4:netty_all_java",
+ ]
+ }
+
+ 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",
+ ]
+ 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 + [
+ ":cronet_jni_registration",
+ "//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_with_pydeps("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 ]
+ _annotations_jar = "$root_out_dir/lib.java/third_party/androidx/androidx_annotation_annotation.jar"
+ _src_jar = "$_package_dir/cronet_api-src.jar"
+ inputs = [
+ _annotations_jar,
+ _src_jar,
+ android_sdk_jar,
+ ]
+
+ 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),
+ "--support-annotations-jar",
+ rebase_path(_annotations_jar, root_build_dir),
+
+ # JavaDoc is generated from Cronet's API source jar.
+ "--input-src-jar",
+ rebase_path(_src_jar, root_build_dir),
+ ]
+ deps = [
+ ":jar_cronet_api_source",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+ }
+
+ 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_fake_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_fake_base_java",
+ ":cronet_impl_platform_base_java",
+ ]
+ }
+
+ copy("cronet_package_copy_native_headers") {
+ sources = cronet_native_public_headers + grpc_public_headers
+
+ outputs = [ "$_package_dir/include/{{source_file_part}}" ]
+ }
+
+ 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/testing/test_server/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/expired_cert.pem",
+ "//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",
+ "//net/data/ssl/certificates/root_ca_cert.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" ]
+ _api_jar =
+ "$root_build_dir/lib.java/components/cronet/android/cronet_api_java.jar"
+ _common_jar = "$root_build_dir/lib.java/components/cronet/android/cronet_impl_common_base_java.jar"
+ _platform_jar = "$root_build_dir/lib.java/components/cronet/android/cronet_impl_platform_base_java.jar"
+ _native_jar = "$root_build_dir/lib.java/components/cronet/android/cronet_impl_native_base_java.jar"
+ args = [
+ "--api_jar",
+ rebase_path(_api_jar, root_build_dir),
+ "--impl_jar",
+ rebase_path(_common_jar, root_build_dir),
+ "--impl_jar",
+ rebase_path(_platform_jar, root_build_dir),
+ "--impl_jar",
+ rebase_path(_native_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 = [
+ _api_jar,
+ _common_jar,
+ _platform_jar,
+ _native_jar,
+ "//components/cronet/tools/update_api.py",
+ ]
+ sources = [
+ "//components/cronet/android/api.txt",
+ "//components/cronet/android/api_version.txt",
+ ]
+ }
+
+ group("cronet_package_android") {
+ # 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",
+ ":cronet_package_copy",
+ ":cronet_package_copy_native_headers",
+ ":cronet_package_copy_native_lib",
+ ":cronet_package_copy_native_lib_unstripped",
+ ":cronet_package_copy_resources",
+ ":cronet_sizes",
+ ":cronet_test_package",
+ ":generate_javadoc",
+ ":generate_licenses",
+ ":jar_cronet_api_source",
+ ":jar_cronet_impl_common_java_source",
+ ":jar_cronet_impl_fake_java_source",
+ ":jar_cronet_impl_native_java_source",
+ ":jar_cronet_impl_platform_java_source",
+ ":jar_cronet_sample_source",
+ ":repackage_api",
+ ":repackage_common",
+ ":repackage_fake",
+ ":repackage_native",
+ ":repackage_platform",
+ ]
+ 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_test_jars",
+ ]
+ }
+ }
+}
diff --git a/src/components/cronet/android/DEPS b/src/components/cronet/android/DEPS
new file mode 100644
index 0000000000..d6643eb64b
--- /dev/null
+++ b/src/components/cronet/android/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+ "+components/metrics",
+ "+crypto",
+ "+jni",
+]
diff --git a/src/components/cronet/android/OWNERS b/src/components/cronet/android/OWNERS
new file mode 100644
index 0000000000..22fd905f29
--- /dev/null
+++ b/src/components/cronet/android/OWNERS
@@ -0,0 +1 @@
+per-file lint-*.xml=*
diff --git a/src/components/cronet/android/android_only_jni_onload_and_cronet_exports.lst b/src/components/cronet/android/android_only_jni_onload_and_cronet_exports.lst
new file mode 100644
index 0000000000..363860d0dc
--- /dev/null
+++ b/src/components/cronet/android/android_only_jni_onload_and_cronet_exports.lst
@@ -0,0 +1,13 @@
+# Copyright 2017 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.
+
+# Linker script that exports only symbols required for JNI and Cronet Native
+# API to work.
+{
+ global:
+ JNI_OnLoad;
+ Cronet_*;
+ local:
+ *;
+};
diff --git a/src/components/cronet/android/api.txt b/src/components/cronet/android/api.txt
new file mode 100644
index 0000000000..ba238fa0b3
--- /dev/null
+++ b/src/components/cronet/android/api.txt
@@ -0,0 +1,401 @@
+DO NOT EDIT THIS FILE, USE update_api.py TO UPDATE IT
+
+public class org.chromium.net.ApiVersion {
+ public static java.lang.String getCronetVersionWithLastChange();
+ public static int getMaximumAvailableApiLevel();
+ public static int getApiLevel();
+ public static java.lang.String getCronetVersion();
+ public static java.lang.String getLastChange();
+}
+public abstract class org.chromium.net.BidirectionalStream$Builder {
+ public static final int STREAM_PRIORITY_IDLE;
+ public static final int STREAM_PRIORITY_LOWEST;
+ public static final int STREAM_PRIORITY_LOW;
+ public static final int STREAM_PRIORITY_MEDIUM;
+ public static final int STREAM_PRIORITY_HIGHEST;
+ public org.chromium.net.BidirectionalStream$Builder();
+ public abstract org.chromium.net.BidirectionalStream$Builder setHttpMethod(java.lang.String);
+ public abstract org.chromium.net.BidirectionalStream$Builder addHeader(java.lang.String, java.lang.String);
+ public abstract org.chromium.net.BidirectionalStream$Builder setPriority(int);
+ public abstract org.chromium.net.BidirectionalStream$Builder delayRequestHeadersUntilFirstFlush(boolean);
+ public abstract org.chromium.net.BidirectionalStream build();
+}
+public abstract class org.chromium.net.BidirectionalStream$Callback {
+ public org.chromium.net.BidirectionalStream$Callback();
+ public abstract void onStreamReady(org.chromium.net.BidirectionalStream);
+ public abstract void onResponseHeadersReceived(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo);
+ public abstract void onReadCompleted(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer, boolean);
+ public abstract void onWriteCompleted(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer, boolean);
+ public void onResponseTrailersReceived(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo, org.chromium.net.UrlResponseInfo$HeaderBlock);
+ public abstract void onSucceeded(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo);
+ public abstract void onFailed(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo, org.chromium.net.CronetException);
+ public void onCanceled(org.chromium.net.BidirectionalStream, org.chromium.net.UrlResponseInfo);
+}
+public abstract class org.chromium.net.BidirectionalStream {
+ public org.chromium.net.BidirectionalStream();
+ public abstract void start();
+ public abstract void read(java.nio.ByteBuffer);
+ public abstract void write(java.nio.ByteBuffer, boolean);
+ public abstract void flush();
+ public abstract void cancel();
+ public abstract boolean isDone();
+}
+public abstract class org.chromium.net.CallbackException extends org.chromium.net.CronetException {
+ protected org.chromium.net.CallbackException(java.lang.String, java.lang.Throwable);
+}
+public abstract class org.chromium.net.CronetEngine$Builder$LibraryLoader {
+ public org.chromium.net.CronetEngine$Builder$LibraryLoader();
+ public abstract void loadLibrary(java.lang.String);
+}
+public class org.chromium.net.CronetEngine$Builder {
+ protected final org.chromium.net.ICronetEngineBuilder mBuilderDelegate;
+ public static final int HTTP_CACHE_DISABLED;
+ public static final int HTTP_CACHE_IN_MEMORY;
+ public static final int HTTP_CACHE_DISK_NO_HTTP;
+ public static final int HTTP_CACHE_DISK;
+ public org.chromium.net.CronetEngine$Builder(android.content.Context);
+ public org.chromium.net.CronetEngine$Builder(org.chromium.net.ICronetEngineBuilder);
+ public java.lang.String getDefaultUserAgent();
+ public org.chromium.net.CronetEngine$Builder setUserAgent(java.lang.String);
+ public org.chromium.net.CronetEngine$Builder setStoragePath(java.lang.String);
+ public org.chromium.net.CronetEngine$Builder setLibraryLoader(org.chromium.net.CronetEngine$Builder$LibraryLoader);
+ public org.chromium.net.CronetEngine$Builder enableQuic(boolean);
+ public org.chromium.net.CronetEngine$Builder enableHttp2(boolean);
+ public org.chromium.net.CronetEngine$Builder enableSdch(boolean);
+ public org.chromium.net.CronetEngine$Builder enableBrotli(boolean);
+ public org.chromium.net.CronetEngine$Builder enableHttpCache(int, long);
+ public org.chromium.net.CronetEngine$Builder addQuicHint(java.lang.String, int, int);
+ public org.chromium.net.CronetEngine$Builder addPublicKeyPins(java.lang.String, java.util.Set, boolean, java.util.Date);
+ public org.chromium.net.CronetEngine$Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean);
+ public org.chromium.net.CronetEngine build();
+}
+public abstract class org.chromium.net.CronetEngine {
+ public org.chromium.net.CronetEngine();
+ public abstract java.lang.String getVersionString();
+ public abstract void shutdown();
+ public abstract void startNetLogToFile(java.lang.String, boolean);
+ public abstract void stopNetLog();
+ public abstract byte[] getGlobalMetricsDeltas();
+ public abstract java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
+ public abstract java.net.URLStreamHandlerFactory createURLStreamHandlerFactory();
+ public abstract org.chromium.net.UrlRequest$Builder newUrlRequestBuilder(java.lang.String, org.chromium.net.UrlRequest$Callback, java.util.concurrent.Executor);
+}
+public abstract class org.chromium.net.CronetException extends java.io.IOException {
+ protected org.chromium.net.CronetException(java.lang.String, java.lang.Throwable);
+}
+public abstract class org.chromium.net.CronetProvider {
+ public static final java.lang.String PROVIDER_NAME_APP_PACKAGED;
+ public static final java.lang.String PROVIDER_NAME_FALLBACK;
+ protected final android.content.Context mContext;
+ protected org.chromium.net.CronetProvider(android.content.Context);
+ public abstract org.chromium.net.CronetEngine$Builder createBuilder();
+ public abstract java.lang.String getName();
+ public abstract java.lang.String getVersion();
+ public abstract boolean isEnabled();
+ public java.lang.String toString();
+ public static java.util.List getAllProviders(android.content.Context);
+}
+public abstract class org.chromium.net.ExperimentalBidirectionalStream$Builder extends org.chromium.net.BidirectionalStream$Builder {
+ public org.chromium.net.ExperimentalBidirectionalStream$Builder();
+ public org.chromium.net.ExperimentalBidirectionalStream$Builder addRequestAnnotation(java.lang.Object);
+ public org.chromium.net.ExperimentalBidirectionalStream$Builder setTrafficStatsTag(int);
+ public org.chromium.net.ExperimentalBidirectionalStream$Builder setTrafficStatsUid(int);
+ public abstract org.chromium.net.ExperimentalBidirectionalStream$Builder setHttpMethod(java.lang.String);
+ public abstract org.chromium.net.ExperimentalBidirectionalStream$Builder addHeader(java.lang.String, java.lang.String);
+ public abstract org.chromium.net.ExperimentalBidirectionalStream$Builder setPriority(int);
+ public abstract org.chromium.net.ExperimentalBidirectionalStream$Builder delayRequestHeadersUntilFirstFlush(boolean);
+ public abstract org.chromium.net.ExperimentalBidirectionalStream build();
+ public org.chromium.net.BidirectionalStream build();
+ public org.chromium.net.BidirectionalStream$Builder delayRequestHeadersUntilFirstFlush(boolean);
+ public org.chromium.net.BidirectionalStream$Builder setPriority(int);
+ public org.chromium.net.BidirectionalStream$Builder addHeader(java.lang.String, java.lang.String);
+ public org.chromium.net.BidirectionalStream$Builder setHttpMethod(java.lang.String);
+}
+public abstract class org.chromium.net.ExperimentalBidirectionalStream extends org.chromium.net.BidirectionalStream {
+ public org.chromium.net.ExperimentalBidirectionalStream();
+}
+public class org.chromium.net.ExperimentalCronetEngine$Builder extends org.chromium.net.CronetEngine$Builder {
+ public org.chromium.net.ExperimentalCronetEngine$Builder(android.content.Context);
+ public org.chromium.net.ExperimentalCronetEngine$Builder(org.chromium.net.ICronetEngineBuilder);
+ public org.chromium.net.ExperimentalCronetEngine$Builder enableNetworkQualityEstimator(boolean);
+ public org.chromium.net.ExperimentalCronetEngine$Builder setExperimentalOptions(java.lang.String);
+ public org.chromium.net.ExperimentalCronetEngine$Builder setThreadPriority(int);
+ public org.chromium.net.ICronetEngineBuilder getBuilderDelegate();
+ public org.chromium.net.ExperimentalCronetEngine$Builder setUserAgent(java.lang.String);
+ public org.chromium.net.ExperimentalCronetEngine$Builder setStoragePath(java.lang.String);
+ public org.chromium.net.ExperimentalCronetEngine$Builder setLibraryLoader(org.chromium.net.CronetEngine$Builder$LibraryLoader);
+ public org.chromium.net.ExperimentalCronetEngine$Builder enableQuic(boolean);
+ public org.chromium.net.ExperimentalCronetEngine$Builder enableHttp2(boolean);
+ public org.chromium.net.ExperimentalCronetEngine$Builder enableSdch(boolean);
+ public org.chromium.net.ExperimentalCronetEngine$Builder enableHttpCache(int, long);
+ public org.chromium.net.ExperimentalCronetEngine$Builder addQuicHint(java.lang.String, int, int);
+ public org.chromium.net.ExperimentalCronetEngine$Builder addPublicKeyPins(java.lang.String, java.util.Set, boolean, java.util.Date);
+ public org.chromium.net.ExperimentalCronetEngine$Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean);
+ public org.chromium.net.ExperimentalCronetEngine build();
+ public org.chromium.net.CronetEngine build();
+ public org.chromium.net.CronetEngine$Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean);
+ public org.chromium.net.CronetEngine$Builder addPublicKeyPins(java.lang.String, java.util.Set, boolean, java.util.Date);
+ public org.chromium.net.CronetEngine$Builder addQuicHint(java.lang.String, int, int);
+ public org.chromium.net.CronetEngine$Builder enableHttpCache(int, long);
+ public org.chromium.net.CronetEngine$Builder enableSdch(boolean);
+ public org.chromium.net.CronetEngine$Builder enableHttp2(boolean);
+ public org.chromium.net.CronetEngine$Builder enableQuic(boolean);
+ public org.chromium.net.CronetEngine$Builder setLibraryLoader(org.chromium.net.CronetEngine$Builder$LibraryLoader);
+ public org.chromium.net.CronetEngine$Builder setStoragePath(java.lang.String);
+ public org.chromium.net.CronetEngine$Builder setUserAgent(java.lang.String);
+}
+public abstract class org.chromium.net.ExperimentalCronetEngine extends org.chromium.net.CronetEngine {
+ public static final int CONNECTION_METRIC_UNKNOWN;
+ public static final int EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+ public static final int EFFECTIVE_CONNECTION_TYPE_OFFLINE;
+ public static final int EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
+ public static final int EFFECTIVE_CONNECTION_TYPE_2G;
+ public static final int EFFECTIVE_CONNECTION_TYPE_3G;
+ public static final int EFFECTIVE_CONNECTION_TYPE_4G;
+ public org.chromium.net.ExperimentalCronetEngine();
+ public abstract org.chromium.net.ExperimentalBidirectionalStream$Builder newBidirectionalStreamBuilder(java.lang.String, org.chromium.net.BidirectionalStream$Callback, java.util.concurrent.Executor);
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder newUrlRequestBuilder(java.lang.String, org.chromium.net.UrlRequest$Callback, java.util.concurrent.Executor);
+ public void startNetLogToDisk(java.lang.String, boolean, int);
+ public int getEffectiveConnectionType();
+ public void configureNetworkQualityEstimatorForTesting(boolean, boolean, boolean);
+ public void addRttListener(org.chromium.net.NetworkQualityRttListener);
+ public void removeRttListener(org.chromium.net.NetworkQualityRttListener);
+ public void addThroughputListener(org.chromium.net.NetworkQualityThroughputListener);
+ public void removeThroughputListener(org.chromium.net.NetworkQualityThroughputListener);
+ public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
+ public void addRequestFinishedListener(org.chromium.net.RequestFinishedInfo$Listener);
+ public void removeRequestFinishedListener(org.chromium.net.RequestFinishedInfo$Listener);
+ public int getHttpRttMs();
+ public int getTransportRttMs();
+ public int getDownstreamThroughputKbps();
+ public org.chromium.net.UrlRequest$Builder newUrlRequestBuilder(java.lang.String, org.chromium.net.UrlRequest$Callback, java.util.concurrent.Executor);
+}
+public abstract class org.chromium.net.ExperimentalUrlRequest$Builder extends org.chromium.net.UrlRequest$Builder {
+ public static final int DEFAULT_IDEMPOTENCY;
+ public static final int IDEMPOTENT;
+ public static final int NOT_IDEMPOTENT;
+ public org.chromium.net.ExperimentalUrlRequest$Builder();
+ public org.chromium.net.ExperimentalUrlRequest$Builder disableConnectionMigration();
+ public org.chromium.net.ExperimentalUrlRequest$Builder addRequestAnnotation(java.lang.Object);
+ public org.chromium.net.ExperimentalUrlRequest$Builder setTrafficStatsTag(int);
+ public org.chromium.net.ExperimentalUrlRequest$Builder setTrafficStatsUid(int);
+ public org.chromium.net.ExperimentalUrlRequest$Builder setRequestFinishedListener(org.chromium.net.RequestFinishedInfo$Listener);
+ public org.chromium.net.ExperimentalUrlRequest$Builder setIdempotency(int);
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder setHttpMethod(java.lang.String);
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder addHeader(java.lang.String, java.lang.String);
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder disableCache();
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder setPriority(int);
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor);
+ public abstract org.chromium.net.ExperimentalUrlRequest$Builder allowDirectExecutor();
+ public abstract org.chromium.net.ExperimentalUrlRequest build();
+ public org.chromium.net.UrlRequest build();
+ public org.chromium.net.UrlRequest$Builder allowDirectExecutor();
+ public org.chromium.net.UrlRequest$Builder setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor);
+ public org.chromium.net.UrlRequest$Builder setPriority(int);
+ public org.chromium.net.UrlRequest$Builder disableCache();
+ public org.chromium.net.UrlRequest$Builder addHeader(java.lang.String, java.lang.String);
+ public org.chromium.net.UrlRequest$Builder setHttpMethod(java.lang.String);
+}
+public abstract class org.chromium.net.ExperimentalUrlRequest extends org.chromium.net.UrlRequest {
+ public org.chromium.net.ExperimentalUrlRequest();
+}
+public abstract class org.chromium.net.ICronetEngineBuilder {
+ public org.chromium.net.ICronetEngineBuilder();
+ public abstract org.chromium.net.ICronetEngineBuilder addPublicKeyPins(java.lang.String, java.util.Set, boolean, java.util.Date);
+ public abstract org.chromium.net.ICronetEngineBuilder addQuicHint(java.lang.String, int, int);
+ public abstract org.chromium.net.ICronetEngineBuilder enableHttp2(boolean);
+ public abstract org.chromium.net.ICronetEngineBuilder enableHttpCache(int, long);
+ public abstract org.chromium.net.ICronetEngineBuilder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean);
+ public abstract org.chromium.net.ICronetEngineBuilder enableQuic(boolean);
+ public abstract org.chromium.net.ICronetEngineBuilder enableSdch(boolean);
+ public org.chromium.net.ICronetEngineBuilder enableBrotli(boolean);
+ public abstract org.chromium.net.ICronetEngineBuilder setExperimentalOptions(java.lang.String);
+ public abstract org.chromium.net.ICronetEngineBuilder setLibraryLoader(org.chromium.net.CronetEngine$Builder$LibraryLoader);
+ public abstract org.chromium.net.ICronetEngineBuilder setStoragePath(java.lang.String);
+ public abstract org.chromium.net.ICronetEngineBuilder setUserAgent(java.lang.String);
+ public abstract java.lang.String getDefaultUserAgent();
+ public abstract org.chromium.net.ExperimentalCronetEngine build();
+ public org.chromium.net.ICronetEngineBuilder enableNetworkQualityEstimator(boolean);
+ public org.chromium.net.ICronetEngineBuilder setThreadPriority(int);
+}
+public final class org.chromium.net.InlineExecutionProhibitedException extends java.util.concurrent.RejectedExecutionException {
+ public org.chromium.net.InlineExecutionProhibitedException();
+}
+public abstract class org.chromium.net.NetworkException extends org.chromium.net.CronetException {
+ public static final int ERROR_HOSTNAME_NOT_RESOLVED;
+ public static final int ERROR_INTERNET_DISCONNECTED;
+ public static final int ERROR_NETWORK_CHANGED;
+ public static final int ERROR_TIMED_OUT;
+ public static final int ERROR_CONNECTION_CLOSED;
+ public static final int ERROR_CONNECTION_TIMED_OUT;
+ public static final int ERROR_CONNECTION_REFUSED;
+ public static final int ERROR_CONNECTION_RESET;
+ public static final int ERROR_ADDRESS_UNREACHABLE;
+ public static final int ERROR_QUIC_PROTOCOL_FAILED;
+ public static final int ERROR_OTHER;
+ protected org.chromium.net.NetworkException(java.lang.String, java.lang.Throwable);
+ public abstract int getErrorCode();
+ public abstract int getCronetInternalErrorCode();
+ public abstract boolean immediatelyRetryable();
+}
+public abstract class org.chromium.net.NetworkQualityRttListener {
+ public org.chromium.net.NetworkQualityRttListener(java.util.concurrent.Executor);
+ public java.util.concurrent.Executor getExecutor();
+ public abstract void onRttObservation(int, long, int);
+}
+public abstract class org.chromium.net.NetworkQualityThroughputListener {
+ public org.chromium.net.NetworkQualityThroughputListener(java.util.concurrent.Executor);
+ public java.util.concurrent.Executor getExecutor();
+ public abstract void onThroughputObservation(int, long, int);
+}
+public abstract class org.chromium.net.QuicException extends org.chromium.net.NetworkException {
+ protected org.chromium.net.QuicException(java.lang.String, java.lang.Throwable);
+ public abstract int getQuicDetailedErrorCode();
+}
+public abstract class org.chromium.net.RequestFinishedInfo$Listener {
+ public org.chromium.net.RequestFinishedInfo$Listener(java.util.concurrent.Executor);
+ public abstract void onRequestFinished(org.chromium.net.RequestFinishedInfo);
+ public java.util.concurrent.Executor getExecutor();
+}
+public abstract class org.chromium.net.RequestFinishedInfo$Metrics {
+ public org.chromium.net.RequestFinishedInfo$Metrics();
+ public abstract java.util.Date getRequestStart();
+ public abstract java.util.Date getDnsStart();
+ public abstract java.util.Date getDnsEnd();
+ public abstract java.util.Date getConnectStart();
+ public abstract java.util.Date getConnectEnd();
+ public abstract java.util.Date getSslStart();
+ public abstract java.util.Date getSslEnd();
+ public abstract java.util.Date getSendingStart();
+ public abstract java.util.Date getSendingEnd();
+ public abstract java.util.Date getPushStart();
+ public abstract java.util.Date getPushEnd();
+ public abstract java.util.Date getResponseStart();
+ public abstract java.util.Date getRequestEnd();
+ public abstract boolean getSocketReused();
+ public abstract java.lang.Long getTtfbMs();
+ public abstract java.lang.Long getTotalTimeMs();
+ public abstract java.lang.Long getSentByteCount();
+ public abstract java.lang.Long getReceivedByteCount();
+}
+public abstract class org.chromium.net.RequestFinishedInfo {
+ public static final int SUCCEEDED;
+ public static final int FAILED;
+ public static final int CANCELED;
+ public org.chromium.net.RequestFinishedInfo();
+ public abstract java.lang.String getUrl();
+ public abstract java.util.Collection getAnnotations();
+ public abstract org.chromium.net.RequestFinishedInfo$Metrics getMetrics();
+ public abstract int getFinishedReason();
+ public abstract org.chromium.net.UrlResponseInfo getResponseInfo();
+ public abstract org.chromium.net.CronetException getException();
+}
+public abstract class org.chromium.net.UploadDataProvider implements java.io.Closeable {
+ public org.chromium.net.UploadDataProvider();
+ public abstract long getLength() throws java.io.IOException;
+ public abstract void read(org.chromium.net.UploadDataSink, java.nio.ByteBuffer) throws java.io.IOException;
+ public abstract void rewind(org.chromium.net.UploadDataSink) throws java.io.IOException;
+ public void close() throws java.io.IOException;
+}
+final class org.chromium.net.UploadDataProviders$ByteBufferUploadProvider extends org.chromium.net.UploadDataProvider {
+ public long getLength();
+ public void read(org.chromium.net.UploadDataSink, java.nio.ByteBuffer);
+ public void rewind(org.chromium.net.UploadDataSink);
+}
+interface org.chromium.net.UploadDataProviders$FileChannelProvider {
+ public abstract java.nio.channels.FileChannel getChannel() throws java.io.IOException;
+}
+final class org.chromium.net.UploadDataProviders$FileUploadProvider extends org.chromium.net.UploadDataProvider {
+ public long getLength() throws java.io.IOException;
+ public void read(org.chromium.net.UploadDataSink, java.nio.ByteBuffer) throws java.io.IOException;
+ public void rewind(org.chromium.net.UploadDataSink) throws java.io.IOException;
+ public void close() throws java.io.IOException;
+}
+public final class org.chromium.net.UploadDataProviders {
+ public static org.chromium.net.UploadDataProvider create(java.io.File);
+ public static org.chromium.net.UploadDataProvider create(android.os.ParcelFileDescriptor);
+ public static org.chromium.net.UploadDataProvider create(java.nio.ByteBuffer);
+ public static org.chromium.net.UploadDataProvider create(byte[], int, int);
+ public static org.chromium.net.UploadDataProvider create(byte[]);
+}
+public abstract class org.chromium.net.UploadDataSink {
+ public org.chromium.net.UploadDataSink();
+ public abstract void onReadSucceeded(boolean);
+ public abstract void onReadError(java.lang.Exception);
+ public abstract void onRewindSucceeded();
+ public abstract void onRewindError(java.lang.Exception);
+}
+public abstract class org.chromium.net.UrlRequest$Builder {
+ public static final int REQUEST_PRIORITY_IDLE;
+ public static final int REQUEST_PRIORITY_LOWEST;
+ public static final int REQUEST_PRIORITY_LOW;
+ public static final int REQUEST_PRIORITY_MEDIUM;
+ public static final int REQUEST_PRIORITY_HIGHEST;
+ public org.chromium.net.UrlRequest$Builder();
+ public abstract org.chromium.net.UrlRequest$Builder setHttpMethod(java.lang.String);
+ public abstract org.chromium.net.UrlRequest$Builder addHeader(java.lang.String, java.lang.String);
+ public abstract org.chromium.net.UrlRequest$Builder disableCache();
+ public abstract org.chromium.net.UrlRequest$Builder setPriority(int);
+ public abstract org.chromium.net.UrlRequest$Builder setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor);
+ public abstract org.chromium.net.UrlRequest$Builder allowDirectExecutor();
+ public abstract org.chromium.net.UrlRequest build();
+}
+public abstract class org.chromium.net.UrlRequest$Callback {
+ public org.chromium.net.UrlRequest$Callback();
+ public abstract void onRedirectReceived(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.lang.String) throws java.lang.Exception;
+ public abstract void onResponseStarted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) throws java.lang.Exception;
+ public abstract void onReadCompleted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer) throws java.lang.Exception;
+ public abstract void onSucceeded(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo);
+ public abstract void onFailed(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, org.chromium.net.CronetException);
+ public void onCanceled(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo);
+}
+public class org.chromium.net.UrlRequest$Status {
+ public static final int INVALID;
+ public static final int IDLE;
+ public static final int WAITING_FOR_STALLED_SOCKET_POOL;
+ public static final int WAITING_FOR_AVAILABLE_SOCKET;
+ public static final int WAITING_FOR_DELEGATE;
+ public static final int WAITING_FOR_CACHE;
+ public static final int DOWNLOADING_PAC_FILE;
+ public static final int RESOLVING_PROXY_FOR_URL;
+ public static final int RESOLVING_HOST_IN_PAC_FILE;
+ public static final int ESTABLISHING_PROXY_TUNNEL;
+ public static final int RESOLVING_HOST;
+ public static final int CONNECTING;
+ public static final int SSL_HANDSHAKE;
+ public static final int SENDING_REQUEST;
+ public static final int WAITING_FOR_RESPONSE;
+ public static final int READING_RESPONSE;
+}
+public abstract class org.chromium.net.UrlRequest$StatusListener {
+ public org.chromium.net.UrlRequest$StatusListener();
+ public abstract void onStatus(int);
+}
+public abstract class org.chromium.net.UrlRequest {
+ public org.chromium.net.UrlRequest();
+ public abstract void start();
+ public abstract void followRedirect();
+ public abstract void read(java.nio.ByteBuffer);
+ public abstract void cancel();
+ public abstract boolean isDone();
+ public abstract void getStatus(org.chromium.net.UrlRequest$StatusListener);
+}
+public abstract class org.chromium.net.UrlResponseInfo$HeaderBlock {
+ public org.chromium.net.UrlResponseInfo$HeaderBlock();
+ public abstract java.util.List> getAsList();
+ public abstract java.util.Map> getAsMap();
+}
+public abstract class org.chromium.net.UrlResponseInfo {
+ public org.chromium.net.UrlResponseInfo();
+ public abstract java.lang.String getUrl();
+ public abstract java.util.List getUrlChain();
+ public abstract int getHttpStatusCode();
+ public abstract java.lang.String getHttpStatusText();
+ public abstract java.util.List> getAllHeadersAsList();
+ public abstract java.util.Map> getAllHeaders();
+ public abstract boolean wasCached();
+ public abstract java.lang.String getNegotiatedProtocol();
+ public abstract java.lang.String getProxyServer();
+ public abstract long getReceivedByteCount();
+}
+Stamp: 1c548f381e3715d983e967e830d675d8
diff --git a/src/components/cronet/android/api/res/raw/keep_cronet_api.xml b/src/components/cronet/android/api/res/raw/keep_cronet_api.xml
new file mode 100644
index 0000000000..b87be37516
--- /dev/null
+++ b/src/components/cronet/android/api/res/raw/keep_cronet_api.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/src/components/cronet/android/api/src/org/chromium/net/ApiVersion.template b/src/components/cronet/android/api/src/org/chromium/net/ApiVersion.template
new file mode 100644
index 0000000000..4c32f80cc3
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/ApiVersion.template
@@ -0,0 +1,63 @@
+// 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.
+
+package org.chromium.net;
+
+/**
+ * Version based on chrome/VERSION.
+ * {@hide as it's only used internally}
+ */
+public class ApiVersion {
+ private static final String CRONET_VERSION = "@MAJOR@.@MINOR@.@BUILD@.@PATCH@";
+ private static final int API_LEVEL = @API_LEVEL@;
+ /**
+ * The minimum API level of implementations that are compatible with this API.
+ * The last API level which broke backwards API compatibility. In other words, the
+ * Cronet API that this class is part of won't work with Cronet implementations that implement
+ * API levels less than this value. That is if
+ * ImplVersion.getApiLevel() < ApiVersion.getApiLevel(), then the Cronet implementation
+ * providing ImplVersion cannot be used with the Cronet API providing ApiVersion; if they are
+ * used together various unexpected Errors, like AbstractMethodError, may result.
+ */
+ private static final int MIN_COMPATIBLE_API_LEVEL = 3;
+ private static final String LAST_CHANGE = "@LASTCHANGE@";
+
+ /**
+ * Private constructor. All members of this class should be static.
+ */
+ private ApiVersion() {}
+
+ public static String getCronetVersionWithLastChange() {
+ return CRONET_VERSION + "@" + LAST_CHANGE.substring(0, 8);
+ }
+
+ /**
+ * Returns API level of the API linked into the application. This is the maximum API
+ * level the application can use, even if the application is run with a newer implementation.
+ */
+ public static int getMaximumAvailableApiLevel() {
+ return API_LEVEL;
+ }
+
+ /**
+ * The minimum API level of implementations that are compatible with this API.
+ * Returns the last API level which broke backwards API compatibility. In other words, the
+ * Cronet API that this class is part of won't work with Cronet implementations that implement
+ * API levels less than this value. That is if
+ * ImplVersion.getApiLevel() < ApiVersion.getApiLevel(), then the Cronet implementation
+ * providing ImplVersion cannot be used with the Cronet API providing ApiVersion; if they are
+ * used together various unexpected Errors, like AbstractMethodError, may result.
+ */
+ public static int getApiLevel() {
+ return MIN_COMPATIBLE_API_LEVEL;
+ }
+
+ public static String getCronetVersion() {
+ return CRONET_VERSION;
+ }
+
+ public static String getLastChange() {
+ return LAST_CHANGE;
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/BidirectionalStream.java b/src/components/cronet/android/api/src/org/chromium/net/BidirectionalStream.java
new file mode 100644
index 0000000000..e21a8fc28c
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/BidirectionalStream.java
@@ -0,0 +1,303 @@
+// 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.
+
+package org.chromium.net;
+
+import android.annotation.SuppressLint;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.Executor;
+
+/**
+ * Class for bidirectional sending and receiving of data over HTTP/2 or QUIC connections.
+ * Created by {@link Builder}.
+ *
+ * Note: There are ordering restrictions on methods of {@link BidirectionalStream};
+ * please see individual methods for description of restrictions.
+ *
+ * {@hide experimental}
+ */
+public abstract class BidirectionalStream {
+ /**
+ * Builder for {@link BidirectionalStream}s. Allows configuring stream before constructing
+ * it via {@link Builder#build}. Created by
+ * {@link ExperimentalCronetEngine#newBidirectionalStreamBuilder}.
+ */
+ public abstract static class Builder {
+ /**
+ * Sets the HTTP method for the request. Returns builder to facilitate chaining.
+ *
+ * @param method the method to use for request. Default is 'POST'
+ * @return the builder to facilitate chaining
+ */
+ public abstract Builder setHttpMethod(String method);
+
+ /**
+ * Adds a request header. Returns builder to facilitate chaining.
+ *
+ * @param header the header name
+ * @param value the header value
+ * @return the builder to facilitate chaining
+ */
+ public abstract Builder addHeader(String header, String value);
+
+ /**
+ * Lowest stream priority. Passed to {@link #setPriority}.
+ */
+ public static final int STREAM_PRIORITY_IDLE = 0;
+ /**
+ * Very low stream priority. Passed to {@link #setPriority}.
+ */
+ public static final int STREAM_PRIORITY_LOWEST = 1;
+ /**
+ * Low stream priority. Passed to {@link #setPriority}.
+ */
+ public static final int STREAM_PRIORITY_LOW = 2;
+ /**
+ * Medium stream priority. Passed to {@link #setPriority}. This is the
+ * default priority given to the stream.
+ */
+ public static final int STREAM_PRIORITY_MEDIUM = 3;
+ /**
+ * Highest stream priority. Passed to {@link #setPriority}.
+ */
+ public static final int STREAM_PRIORITY_HIGHEST = 4;
+
+ /**
+ * Sets priority of the stream which should be one of the
+ * {@link #STREAM_PRIORITY_IDLE STREAM_PRIORITY_*} values.
+ * The stream is given {@link #STREAM_PRIORITY_MEDIUM} priority if
+ * this method is not called.
+ *
+ * @param priority priority of the stream which should be one of the
+ * {@link #STREAM_PRIORITY_IDLE STREAM_PRIORITY_*} values.
+ * @return the builder to facilitate chaining.
+ */
+ public abstract Builder setPriority(int priority);
+
+ /**
+ * Delays sending request headers until {@link BidirectionalStream#flush()}
+ * is called. This flag is currently only respected when QUIC is negotiated.
+ * When true, QUIC will send request header frame along with data frame(s)
+ * as a single packet when possible.
+ *
+ * @param delayRequestHeadersUntilFirstFlush if true, sending request headers will
+ * be delayed until flush() is called.
+ * @return the builder to facilitate chaining.
+ */
+ public abstract Builder delayRequestHeadersUntilFirstFlush(
+ boolean delayRequestHeadersUntilFirstFlush);
+
+ /**
+ * Creates a {@link BidirectionalStream} using configuration from this
+ * {@link Builder}. The returned {@code BidirectionalStream} can then be started
+ * by calling {@link BidirectionalStream#start}.
+ *
+ * @return constructed {@link BidirectionalStream} using configuration from
+ * this {@link Builder}
+ */
+ @SuppressLint("WrongConstant") // TODO(jbudorick): Remove this after rolling to the N SDK.
+ public abstract BidirectionalStream build();
+ }
+
+ /**
+ * Callback class used to receive callbacks from a {@link BidirectionalStream}.
+ */
+ public abstract static class Callback {
+ /**
+ * Invoked when the stream is ready for reading and writing.
+ * Consumer may call {@link BidirectionalStream#read read()} to start reading data.
+ * Consumer may call {@link BidirectionalStream#write write()} to start writing data.
+ *
+ * @param stream the stream that is ready.
+ */
+ public abstract void onStreamReady(BidirectionalStream stream);
+
+ /**
+ * Invoked when initial response headers are received. Headers are available from
+ * {@code info.}{@link UrlResponseInfo#getAllHeaders getAllHeaders()}.
+ * Consumer may call {@link BidirectionalStream#read read()} to start reading.
+ * Consumer may call {@link BidirectionalStream#write write()} to start writing or close the
+ * stream.
+ *
+ * @param stream the stream on which response headers were received.
+ * @param info the response information.
+ */
+ public abstract void onResponseHeadersReceived(
+ BidirectionalStream stream, UrlResponseInfo info);
+
+ /**
+ * Invoked when data is read into the buffer passed to {@link BidirectionalStream#read
+ * read()}. Only part of the buffer may be populated. To continue reading, call {@link
+ * BidirectionalStream#read read()}. It may be invoked after {@code
+ * onResponseTrailersReceived()}, if there was pending read data before trailers were
+ * received.
+ *
+ * @param stream the stream on which the read completed
+ * @param info the response information
+ * @param buffer the buffer that was passed to {@link BidirectionalStream#read read()},
+ * now containing the received data. The buffer's limit is not changed.
+ * The buffer's position is set to the end of the received data. If position is not
+ * updated, it means the remote side has signaled that it will send no more data.
+ * @param endOfStream if true, this is the last read data, remote will not send more data,
+ * and the read side is closed.
+ *
+ */
+ public abstract void onReadCompleted(BidirectionalStream stream, UrlResponseInfo info,
+ ByteBuffer buffer, boolean endOfStream);
+
+ /**
+ * Invoked when the entire ByteBuffer passed to {@link BidirectionalStream#write write()}
+ * is sent. The buffer's position is updated to be the same as the buffer's limit.
+ * The buffer's limit is not changed. To continue writing, call
+ * {@link BidirectionalStream#write write()}.
+ *
+ * @param stream the stream on which the write completed
+ * @param info the response information
+ * @param buffer the buffer that was passed to {@link BidirectionalStream#write write()}.
+ * The buffer's position is set to the buffer's limit. The buffer's limit
+ * is not changed.
+ * @param endOfStream the endOfStream flag that was passed to the corresponding
+ * {@link BidirectionalStream#write write()}. If true, the write side is closed.
+ */
+ public abstract void onWriteCompleted(BidirectionalStream stream, UrlResponseInfo info,
+ ByteBuffer buffer, boolean endOfStream);
+
+ /**
+ * Invoked when trailers are received before closing the stream. Only invoked
+ * when server sends trailers, which it may not. May be invoked while there is read data
+ * remaining in local buffer.
+ *
+ * Default implementation takes no action.
+ *
+ * @param stream the stream on which response trailers were received
+ * @param info the response information
+ * @param trailers the trailers received
+ */
+ public void onResponseTrailersReceived(BidirectionalStream stream, UrlResponseInfo info,
+ UrlResponseInfo.HeaderBlock trailers) {}
+
+ /**
+ * Invoked when there is no data to be read or written and the stream is closed successfully
+ * remotely and locally. Once invoked, no further {@link BidirectionalStream.Callback}
+ * methods will be invoked.
+ *
+ * @param stream the stream which is closed successfully
+ * @param info the response information
+ */
+ public abstract void onSucceeded(BidirectionalStream stream, UrlResponseInfo info);
+
+ /**
+ * Invoked if the stream failed for any reason after {@link BidirectionalStream#start}.
+ * HTTP/2 error codes are
+ * mapped to {@link UrlRequestException#getCronetInternalErrorCode} codes. Once invoked,
+ * no further {@link BidirectionalStream.Callback} methods will be invoked.
+ *
+ * @param stream the stream which has failed
+ * @param info the response information. May be {@code null} if no response was
+ * received.
+ * @param error information about the failure
+ */
+ public abstract void onFailed(
+ BidirectionalStream stream, UrlResponseInfo info, CronetException error);
+
+ /**
+ * Invoked if the stream was canceled via {@link BidirectionalStream#cancel}. Once
+ * invoked, no further {@link BidirectionalStream.Callback} methods will be invoked.
+ * Default implementation takes no action.
+ *
+ * @param stream the stream that was canceled
+ * @param info the response information. May be {@code null} if no response was
+ * received.
+ */
+ public void onCanceled(BidirectionalStream stream, UrlResponseInfo info) {}
+ }
+
+ /**
+ * Starts the stream, all callbacks go to the {@code callback} argument passed to {@link
+ * BidirectionalStream.Builder}'s constructor. Should only be called once.
+ */
+ public abstract void start();
+
+ /**
+ * Reads data from the stream into the provided buffer.
+ * Can only be called at most once in response to each invocation of the
+ * {@link Callback#onStreamReady onStreamReady()}/
+ * {@link Callback#onResponseHeadersReceived onResponseHeadersReceived()} and {@link
+ * Callback#onReadCompleted onReadCompleted()} methods of the {@link
+ * Callback}. Each call will result in an invocation of one of the
+ * {@link Callback Callback}'s {@link Callback#onReadCompleted onReadCompleted()}
+ * method if data is read, or its {@link Callback#onFailed onFailed()} method if
+ * there's an error.
+ *
+ * An attempt to read data into {@code buffer} starting at {@code
+ * buffer.position()} is begun. At most {@code buffer.remaining()} bytes are
+ * read. {@code buffer.position()} is updated upon invocation of {@link
+ * Callback#onReadCompleted onReadCompleted()} to indicate how much data was read.
+ *
+ * @param buffer the {@link ByteBuffer} to read data into. Must be a
+ * direct ByteBuffer. The embedder must not read or modify buffer's
+ * position, limit, or data between its position and limit until
+ * {@link Callback#onReadCompleted onReadCompleted()}, {@link Callback#onCanceled
+ * onCanceled()}, or {@link Callback#onFailed onFailed()} are invoked.
+ */
+ public abstract void read(ByteBuffer buffer);
+
+ /**
+ * Attempts to write data from the provided buffer into the stream.
+ * If auto flush is disabled, data will be sent only after {@link #flush flush()} is called.
+ * Each call will result in an invocation of one of the
+ * {@link Callback Callback}'s {@link Callback#onWriteCompleted onWriteCompleted()}
+ * method if data is sent, or its {@link Callback#onFailed onFailed()} method if
+ * there's an error.
+ *
+ * An attempt to write data from {@code buffer} starting at {@code buffer.position()}
+ * is begun. {@code buffer.remaining()} bytes will be written.
+ * {@link Callback#onWriteCompleted onWriteCompleted()} will be invoked only when the
+ * full ByteBuffer is written.
+ *
+ * @param buffer the {@link ByteBuffer} to write data from. Must be a
+ * direct ByteBuffer. The embedder must not read or modify buffer's
+ * position, limit, or data between its position and limit until
+ * {@link Callback#onWriteCompleted onWriteCompleted()}, {@link Callback#onCanceled
+ * onCanceled()}, or {@link Callback#onFailed onFailed()} are invoked. Can be empty
+ * when {@code endOfStream} is {@code true}.
+ * @param endOfStream if {@code true}, then {@code buffer} is the last buffer to be written,
+ * and once written, stream is closed from the client side, resulting in half-closed
+ * stream or a fully closed stream if the remote side has already closed.
+ */
+ public abstract void write(ByteBuffer buffer, boolean endOfStream);
+
+ /**
+ * Flushes pending writes. This method should not be invoked before {@link
+ * Callback#onStreamReady onStreamReady()}. For previously delayed {@link
+ * #write write()}s, a corresponding {@link Callback#onWriteCompleted onWriteCompleted()}
+ * will be invoked when the buffer is sent.
+ */
+ public abstract void flush();
+
+ /**
+ * Cancels the stream. Can be called at any time after {@link #start}.
+ * {@link Callback#onCanceled onCanceled()} will be invoked when cancelation
+ * is complete and no further callback methods will be invoked. If the
+ * stream has completed or has not started, calling {@code cancel()} has no
+ * effect and {@code onCanceled()} will not be invoked. If the
+ * {@link Executor} passed in during {@code BidirectionalStream} construction runs
+ * tasks on a single thread, and {@code cancel()} is called on that thread,
+ * no listener methods (besides {@code onCanceled()}) will be invoked after
+ * {@code cancel()} is called. Otherwise, at most one callback method may be
+ * invoked after {@code cancel()} has completed.
+ */
+ public abstract void cancel();
+
+ /**
+ * Returns {@code true} if the stream was successfully started and is now
+ * done (succeeded, canceled, or failed).
+ *
+ * @return {@code true} if the stream was successfully started and is now
+ * done (completed, canceled, or failed), otherwise returns {@code false}
+ * to indicate stream is not yet started or is in progress.
+ */
+ public abstract boolean isDone();
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/CallbackException.java b/src/components/cronet/android/api/src/org/chromium/net/CallbackException.java
new file mode 100644
index 0000000000..0e1fa61ea9
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/CallbackException.java
@@ -0,0 +1,24 @@
+// Copyright 2016 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.
+
+package org.chromium.net;
+
+/**
+ * Exception passed to {@link UrlRequest.Callback#onFailed UrlRequest.Callback.onFailed()} when
+ * {@link UrlRequest.Callback} or {@link UploadDataProvider} method throws an exception. In this
+ * case {@link java.io.IOException#getCause getCause()} can be used to find the thrown
+ * exception.
+ */
+public abstract class CallbackException extends CronetException {
+ /**
+ * Constructs an exception that wraps {@code cause} thrown by a {@link UrlRequest.Callback}.
+ *
+ * @param message explanation of failure.
+ * @param cause exception thrown by {@link UrlRequest.Callback} that's being wrapped. It is
+ * saved for later retrieval by the {@link java.io.IOException#getCause getCause()}.
+ */
+ protected CallbackException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/src/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
new file mode 100644
index 0000000000..b772052456
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
@@ -0,0 +1,545 @@
+// 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.
+
+package org.chromium.net;
+
+import android.content.Context;
+import android.net.http.HttpResponseCache;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+import javax.net.ssl.HttpsURLConnection;
+/**
+ * An engine to process {@link UrlRequest}s, which uses the best HTTP stack
+ * available on the current platform. An instance of this class can be created
+ * using {@link Builder}.
+ */
+public abstract class CronetEngine {
+ private static final String TAG = CronetEngine.class.getSimpleName();
+
+ /**
+ * A builder for {@link CronetEngine}s, which allows runtime configuration of
+ * {@code CronetEngine}. Configuration options are set on the builder and
+ * then {@link #build} is called to create the {@code CronetEngine}.
+ */
+ // NOTE(kapishnikov): In order to avoid breaking the existing API clients, all future methods
+ // added to this class and other API classes must have default implementation.
+ public static class Builder {
+ /**
+ * A class which provides a method for loading the cronet native library. Apps needing to
+ * implement custom library loading logic can inherit from this class and pass an instance
+ * to {@link CronetEngine.Builder#setLibraryLoader}. For example, this might be required
+ * to work around {@code UnsatisfiedLinkError}s caused by flaky installation on certain
+ * older devices.
+ */
+ public abstract static class LibraryLoader {
+ /**
+ * Loads the native library.
+ * @param libName name of the library to load
+ */
+ public abstract void loadLibrary(String libName);
+ }
+
+ /**
+ * Reference to the actual builder implementation.
+ * {@hide exclude from JavaDoc}.
+ */
+ protected final ICronetEngineBuilder mBuilderDelegate;
+
+ /**
+ * Constructs a {@link Builder} object that facilitates creating a
+ * {@link CronetEngine}. The default configuration enables HTTP/2 and
+ * QUIC, but disables the HTTP cache.
+ *
+ * @param context Android {@link Context}, which is used by
+ * {@link Builder} to retrieve the application
+ * context. A reference to only the application
+ * context will be kept, so as to avoid extending
+ * the lifetime of {@code context} unnecessarily.
+ */
+ public Builder(Context context) {
+ this(createBuilderDelegate(context));
+ }
+
+ /**
+ * Constructs {@link Builder} with a given delegate that provides the actual implementation
+ * of the {@code Builder} methods. This constructor is used only by the internal
+ * implementation.
+ *
+ * @param builderDelegate delegate that provides the actual implementation.
+ *
+ * {@hide}
+ */
+ public Builder(ICronetEngineBuilder builderDelegate) {
+ mBuilderDelegate = builderDelegate;
+ }
+
+ /**
+ * Constructs a User-Agent string including application name and version,
+ * system build version, model and id, and Cronet version.
+ *
+ * @return User-Agent string.
+ */
+ public String getDefaultUserAgent() {
+ return mBuilderDelegate.getDefaultUserAgent();
+ }
+
+ /**
+ * Overrides the User-Agent header for all requests. An explicitly
+ * set User-Agent header (set using
+ * {@link UrlRequest.Builder#addHeader}) will override a value set
+ * using this function.
+ *
+ * @param userAgent the User-Agent string to use for all requests.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setUserAgent(String userAgent) {
+ mBuilderDelegate.setUserAgent(userAgent);
+ return this;
+ }
+
+ /**
+ * Sets directory for HTTP Cache and Cookie Storage. The directory must
+ * exist.
+ *
+ * NOTE: Do not use the same storage directory with more than one
+ * {@code CronetEngine} at a time. Access to the storage directory does
+ * not support concurrent access by multiple {@code CronetEngine}s.
+ *
+ * @param value path to existing directory.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setStoragePath(String value) {
+ mBuilderDelegate.setStoragePath(value);
+ return this;
+ }
+
+ /**
+ * Sets a {@link LibraryLoader} to be used to load the native library.
+ * If not set, the library will be loaded using {@link System#loadLibrary}.
+ * @param loader {@code LibraryLoader} to be used to load the native library.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setLibraryLoader(LibraryLoader loader) {
+ mBuilderDelegate.setLibraryLoader(loader);
+ return this;
+ }
+
+ /**
+ * Sets whether QUIC protocol
+ * is enabled. Defaults to enabled. If QUIC is enabled, then QUIC User Agent Id
+ * containing application name and Cronet version is sent to the server.
+ * @param value {@code true} to enable QUIC, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder enableQuic(boolean value) {
+ mBuilderDelegate.enableQuic(value);
+ return this;
+ }
+
+ /**
+ * Sets whether HTTP/2
+ * protocol is enabled. Defaults to enabled.
+ * @param value {@code true} to enable HTTP/2, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder enableHttp2(boolean value) {
+ mBuilderDelegate.enableHttp2(value);
+ return this;
+ }
+
+ /**
+ * @deprecated SDCH is deprecated in Cronet M63. This method is a no-op.
+ * {@hide exclude from JavaDoc}.
+ */
+ @Deprecated
+ public Builder enableSdch(boolean value) {
+ return this;
+ }
+
+ /**
+ * Sets whether Brotli compression is
+ * enabled. If enabled, Brotli will be advertised in Accept-Encoding request headers.
+ * Defaults to disabled.
+ * @param value {@code true} to enable Brotli, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder enableBrotli(boolean value) {
+ mBuilderDelegate.enableBrotli(value);
+ return this;
+ }
+
+ /**
+ * Setting to disable HTTP cache. Some data may still be temporarily stored in memory.
+ * Passed to {@link #enableHttpCache}.
+ */
+ public static final int HTTP_CACHE_DISABLED = 0;
+
+ /**
+ * Setting to enable in-memory HTTP cache, including HTTP data.
+ * Passed to {@link #enableHttpCache}.
+ */
+ public static final int HTTP_CACHE_IN_MEMORY = 1;
+
+ /**
+ * Setting to enable on-disk cache, excluding HTTP data.
+ * {@link #setStoragePath} must be called prior to passing this constant to
+ * {@link #enableHttpCache}.
+ */
+ public static final int HTTP_CACHE_DISK_NO_HTTP = 2;
+
+ /**
+ * Setting to enable on-disk cache, including HTTP data.
+ * {@link #setStoragePath} must be called prior to passing this constant to
+ * {@link #enableHttpCache}.
+ */
+ public static final int HTTP_CACHE_DISK = 3;
+
+ /**
+ * Enables or disables caching of HTTP data and other information like QUIC
+ * server information.
+ * @param cacheMode control location and type of cached data. Must be one of
+ * {@link #HTTP_CACHE_DISABLED HTTP_CACHE_*}.
+ * @param maxSize maximum size in bytes used to cache data (advisory and maybe
+ * exceeded at times).
+ * @return the builder to facilitate chaining.
+ */
+ public Builder enableHttpCache(int cacheMode, long maxSize) {
+ mBuilderDelegate.enableHttpCache(cacheMode, maxSize);
+ return this;
+ }
+
+ /**
+ * Adds hint that {@code host} supports QUIC.
+ * Note that {@link #enableHttpCache enableHttpCache}
+ * ({@link #HTTP_CACHE_DISK}) is needed to take advantage of 0-RTT
+ * connection establishment between sessions.
+ *
+ * @param host hostname of the server that supports QUIC.
+ * @param port host of the server that supports QUIC.
+ * @param alternatePort alternate port to use for QUIC.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder addQuicHint(String host, int port, int alternatePort) {
+ mBuilderDelegate.addQuicHint(host, port, alternatePort);
+ return this;
+ }
+
+ /**
+ *
+ * Pins a set of public keys for a given host. By pinning a set of public keys,
+ * {@code pinsSha256}, communication with {@code hostName} is required to
+ * authenticate with a certificate with a public key from the set of pinned ones.
+ * An app can pin the public key of the root certificate, any of the intermediate
+ * certificates or the end-entry certificate. Authentication will fail and secure
+ * communication will not be established if none of the public keys is present in the
+ * host's certificate chain, even if the host attempts to authenticate with a
+ * certificate allowed by the device's trusted store of certificates.
+ *
+ *
+ * Calling this method multiple times with the same host name overrides the previously
+ * set pins for the host.
+ *
+ *
+ * More information about the public key pinning can be found in
+ * RFC 7469.
+ *
+ *
+ * @param hostName name of the host to which the public keys should be pinned. A host that
+ * consists only of digits and the dot character is treated as invalid.
+ * @param pinsSha256 a set of pins. Each pin is the SHA-256 cryptographic
+ * hash of the DER-encoded ASN.1 representation of the Subject Public
+ * Key Info (SPKI) of the host's X.509 certificate. Use
+ * {@link java.security.cert.Certificate#getPublicKey()
+ * Certificate.getPublicKey()} and
+ * {@link java.security.Key#getEncoded() Key.getEncoded()}
+ * to obtain DER-encoded ASN.1 representation of the SPKI.
+ * Although, the method does not mandate the presence of the backup pin
+ * that can be used if the control of the primary private key has been
+ * lost, it is highly recommended to supply one.
+ * @param includeSubdomains indicates whether the pinning policy should be applied to
+ * subdomains of {@code hostName}.
+ * @param expirationDate specifies the expiration date for the pins.
+ * @return the builder to facilitate chaining.
+ * @throws NullPointerException if any of the input parameters are {@code null}.
+ * @throws IllegalArgumentException if the given host name is invalid or {@code pinsSha256}
+ * contains a byte array that does not represent a valid
+ * SHA-256 hash.
+ */
+ public Builder addPublicKeyPins(String hostName, Set pinsSha256,
+ boolean includeSubdomains, Date expirationDate) {
+ mBuilderDelegate.addPublicKeyPins(
+ hostName, pinsSha256, includeSubdomains, expirationDate);
+ return this;
+ }
+
+ /**
+ * Enables or disables public key pinning bypass for local trust anchors. Disabling the
+ * bypass for local trust anchors is highly discouraged since it may prohibit the app
+ * from communicating with the pinned hosts. E.g., a user may want to send all traffic
+ * through an SSL enabled proxy by changing the device proxy settings and adding the
+ * proxy certificate to the list of local trust anchor. Disabling the bypass will most
+ * likly prevent the app from sending any traffic to the pinned hosts. For more
+ * information see 'How does key pinning interact with local proxies and filters?' at
+ * https://www.chromium.org/Home/chromium-security/security-faq
+ *
+ * @param value {@code true} to enable the bypass, {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean value) {
+ mBuilderDelegate.enablePublicKeyPinningBypassForLocalTrustAnchors(value);
+ return this;
+ }
+
+ /**
+ * Build a {@link CronetEngine} using this builder's configuration.
+ * @return constructed {@link CronetEngine}.
+ */
+ public CronetEngine build() {
+ return mBuilderDelegate.build();
+ }
+
+ /**
+ * Creates an implementation of {@link ICronetEngineBuilder} that can be used
+ * to delegate the builder calls to. The method uses {@link CronetProvider}
+ * to obtain the list of available providers.
+ *
+ * @param context Android Context to use.
+ * @return the created {@code ICronetEngineBuilder}.
+ */
+ private static ICronetEngineBuilder createBuilderDelegate(Context context) {
+ List providers =
+ new ArrayList<>(CronetProvider.getAllProviders(context));
+ CronetProvider provider = getEnabledCronetProviders(context, providers).get(0);
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG,
+ String.format("Using '%s' provider for creating CronetEngine.Builder.",
+ provider));
+ }
+ return provider.createBuilder().mBuilderDelegate;
+ }
+
+ /**
+ * Returns the list of available and enabled {@link CronetProvider}. The returned list
+ * is sorted based on the provider versions and types.
+ *
+ * @param context Android Context to use.
+ * @param providers the list of enabled and disabled providers to filter out and sort.
+ * @return the sorted list of enabled providers. The list contains at least one provider.
+ * @throws RuntimeException is the list of providers is empty or all of the providers
+ * are disabled.
+ */
+ @VisibleForTesting
+ static List getEnabledCronetProviders(
+ Context context, List providers) {
+ // Check that there is at least one available provider.
+ if (providers.size() == 0) {
+ throw new RuntimeException("Unable to find any Cronet provider."
+ + " Have you included all necessary jars?");
+ }
+
+ // Exclude disabled providers from the list.
+ for (Iterator i = providers.iterator(); i.hasNext();) {
+ CronetProvider provider = i.next();
+ if (!provider.isEnabled()) {
+ i.remove();
+ }
+ }
+
+ // Check that there is at least one enabled provider.
+ if (providers.size() == 0) {
+ throw new RuntimeException("All available Cronet providers are disabled."
+ + " A provider should be enabled before it can be used.");
+ }
+
+ // Sort providers based on version and type.
+ Collections.sort(providers, new Comparator() {
+ @Override
+ public int compare(CronetProvider p1, CronetProvider p2) {
+ // The fallback provider should always be at the end of the list.
+ if (CronetProvider.PROVIDER_NAME_FALLBACK.equals(p1.getName())) {
+ return 1;
+ }
+ if (CronetProvider.PROVIDER_NAME_FALLBACK.equals(p2.getName())) {
+ return -1;
+ }
+ // A provider with higher version should go first.
+ return -compareVersions(p1.getVersion(), p2.getVersion());
+ }
+ });
+ return providers;
+ }
+
+ /**
+ * Compares two strings that contain versions. The string should only contain
+ * dot-separated segments that contain an arbitrary number of digits digits [0-9].
+ *
+ * @param s1 the first string.
+ * @param s2 the second string.
+ * @return -1 if s1s2 and 0 if s1=s2. If two versions are equal, the
+ * version with the higher number of segments is considered to be higher.
+ *
+ * @throws IllegalArgumentException if any of the strings contains an illegal
+ * version number.
+ */
+ @VisibleForTesting
+ static int compareVersions(String s1, String s2) {
+ if (s1 == null || s2 == null) {
+ throw new IllegalArgumentException("The input values cannot be null");
+ }
+ String[] s1segments = s1.split("\\.");
+ String[] s2segments = s2.split("\\.");
+ for (int i = 0; i < s1segments.length && i < s2segments.length; i++) {
+ try {
+ int s1segment = Integer.parseInt(s1segments[i]);
+ int s2segment = Integer.parseInt(s2segments[i]);
+ if (s1segment != s2segment) {
+ return Integer.signum(s1segment - s2segment);
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Unable to convert version segments into"
+ + " integers: " + s1segments[i] + " & " + s2segments[i],
+ e);
+ }
+ }
+ return Integer.signum(s1segments.length - s2segments.length);
+ }
+ }
+
+ /**
+ * @return a human-readable version string of the engine.
+ */
+ public abstract String getVersionString();
+
+ /**
+ * Shuts down the {@link CronetEngine} if there are no active requests,
+ * otherwise throws an exception.
+ *
+ * Cannot be called on network thread - the thread Cronet calls into
+ * Executor on (which is different from the thread the Executor invokes
+ * callbacks on). May block until all the {@code CronetEngine}'s
+ * resources have been cleaned up.
+ */
+ public abstract void shutdown();
+
+ /**
+ * Starts NetLog logging to a file. The NetLog will contain events emitted
+ * by all live CronetEngines. The NetLog is useful for debugging.
+ * The file can be viewed using a Chrome browser navigated to
+ * chrome://net-internals/#import
+ * @param fileName the complete file path. It must not be empty. If the file
+ * exists, it is truncated before starting. If actively logging,
+ * this method is ignored.
+ * @param logAll {@code true} to include basic events, user cookies,
+ * credentials and all transferred bytes in the log. This option presents
+ * a privacy risk, since it exposes the user's credentials, and should
+ * only be used with the user's consent and in situations where the log
+ * won't be public.
+ * {@code false} to just include basic events.
+ */
+ public abstract void startNetLogToFile(String fileName, boolean logAll);
+
+ /**
+ * Stops NetLog logging and flushes file to disk. If a logging session is
+ * not in progress, this call is ignored.
+ */
+ public abstract void stopNetLog();
+
+ /**
+ * Returns differences in metrics collected by Cronet since the last call to
+ * this method.
+ *
+ * Cronet collects these metrics globally. This means deltas returned by
+ * {@code getGlobalMetricsDeltas()} will include measurements of requests
+ * processed by other {@link CronetEngine} instances. Since this function
+ * returns differences in metrics collected since the last call, and these
+ * metrics are collected globally, a call to any {@code CronetEngine}
+ * instance's {@code getGlobalMetricsDeltas()} method will affect the deltas
+ * returned by any other {@code CronetEngine} instance's
+ * {@code getGlobalMetricsDeltas()}.
+ *
+ * Cronet starts collecting these metrics after the first call to
+ * {@code getGlobalMetricsDeltras()}, so the first call returns no
+ * useful data as no metrics have yet been collected.
+ *
+ * @return differences in metrics collected by Cronet, since the last call
+ * to {@code getGlobalMetricsDeltas()}, serialized as a
+ * protobuf
+ * .
+ */
+ public abstract byte[] getGlobalMetricsDeltas();
+
+ /**
+ * Establishes a new connection to the resource specified by the {@link URL} {@code url}.
+ *
+ * Note: Cronet's {@link java.net.HttpURLConnection} implementation is subject to certain
+ * limitations, see {@link #createURLStreamHandlerFactory} for details.
+ *
+ * @param url URL of resource to connect to.
+ * @return an {@link java.net.HttpURLConnection} instance implemented by this CronetEngine.
+ * @throws IOException if an error occurs while opening the connection.
+ */
+ public abstract URLConnection openConnection(URL url) throws IOException;
+
+ /**
+ * Creates a {@link URLStreamHandlerFactory} to handle HTTP and HTTPS
+ * traffic. An instance of this class can be installed via
+ * {@link URL#setURLStreamHandlerFactory} thus using this CronetEngine by default for
+ * all requests created via {@link URL#openConnection}.
+ *
+ * Cronet does not use certain HTTP features provided via the system:
+ *
+ *
the HTTP cache installed via
+ * {@link HttpResponseCache#install(java.io.File, long) HttpResponseCache.install()}
+ *
the HTTP authentication method installed via
+ * {@link java.net.Authenticator#setDefault}
+ *
the HTTP cookie storage installed via {@link java.net.CookieHandler#setDefault}
+ *
+ *
+ * While Cronet supports and encourages requests using the HTTPS protocol,
+ * Cronet does not provide support for the
+ * {@link HttpsURLConnection} API. This lack of support also
+ * includes not using certain HTTPS features provided via the system:
+ *
+ *
the HTTPS hostname verifier installed via {@link
+ * HttpsURLConnection#setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier)
+ * HttpsURLConnection.setDefaultHostnameVerifier()}
+ *
the HTTPS socket factory installed via {@link
+ * HttpsURLConnection#setDefaultSSLSocketFactory(javax.net.ssl.SSLSocketFactory)
+ * HttpsURLConnection.setDefaultSSLSocketFactory()}
+ *
+ *
+ * @return an {@link URLStreamHandlerFactory} instance implemented by this
+ * CronetEngine.
+ */
+ public abstract URLStreamHandlerFactory createURLStreamHandlerFactory();
+
+ /**
+ * Creates a builder for {@link UrlRequest}. All callbacks for
+ * generated {@link UrlRequest} objects will be invoked on
+ * {@code executor}'s threads. {@code executor} must not run tasks on the
+ * thread calling {@link Executor#execute} to prevent blocking networking
+ * operations and causing exceptions during shutdown.
+ *
+ * @param url URL for the generated requests.
+ * @param callback callback object that gets invoked on different events.
+ * @param executor {@link Executor} on which all callbacks will be invoked.
+ */
+ public abstract UrlRequest.Builder newUrlRequestBuilder(
+ String url, UrlRequest.Callback callback, Executor executor);
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/CronetException.java b/src/components/cronet/android/api/src/org/chromium/net/CronetException.java
new file mode 100644
index 0000000000..d21a424ac0
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/CronetException.java
@@ -0,0 +1,24 @@
+// 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.
+
+package org.chromium.net;
+
+import java.io.IOException;
+
+/**
+ * Base exception passed to {@link UrlRequest.Callback#onFailed UrlRequest.Callback.onFailed()}.
+ */
+public abstract class CronetException extends IOException {
+ /**
+ * Constructs an exception that is caused by {@code cause}.
+ *
+ * @param message explanation of failure.
+ * @param cause the cause (which is saved for later retrieval by the {@link
+ * java.io.IOException#getCause getCause()} method). A null value is permitted, and
+ * indicates that the cause is nonexistent or unknown.
+ */
+ protected CronetException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/CronetProvider.java b/src/components/cronet/android/api/src/org/chromium/net/CronetProvider.java
new file mode 100644
index 0000000000..c302e647b6
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/CronetProvider.java
@@ -0,0 +1,246 @@
+// Copyright 2017 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.
+
+package org.chromium.net;
+
+import android.content.Context;
+import android.util.Log;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Provides a factory method to create {@link CronetEngine.Builder} instances.
+ * A {@code CronetEngine.Builder} instance can be used to create a specific {@link CronetEngine}
+ * implementation. To get the list of available {@link CronetProvider}s call
+ * {@link #getAllProviders(Context)}.
+ *
+ * NOTE: This class is for advanced users that want to select a particular
+ * Cronet implementation. Most users should simply use {@code new} {@link
+ * CronetEngine.Builder#CronetEngine.Builder(android.content.Context)}.
+ *
+ * {@hide}
+ */
+public abstract class CronetProvider {
+ /**
+ * String returned by {@link CronetProvider#getName} for {@link CronetProvider}
+ * that provides native Cronet implementation packaged inside an application.
+ * This implementation offers significantly higher performance relative to the
+ * fallback Cronet implementations (see {@link #PROVIDER_NAME_FALLBACK}).
+ */
+ public static final String PROVIDER_NAME_APP_PACKAGED = "App-Packaged-Cronet-Provider";
+
+ /**
+ * String returned by {@link CronetProvider#getName} for {@link CronetProvider}
+ * that provides Cronet implementation based on the system's
+ * {@link java.net.HttpURLConnection} implementation. This implementation
+ * offers significantly degraded performance relative to native Cronet
+ * implementations (see {@link #PROVIDER_NAME_APP_PACKAGED}).
+ */
+ public static final String PROVIDER_NAME_FALLBACK = "Fallback-Cronet-Provider";
+
+ /**
+ * The name of an optional key in the app string resource file that contains the class name of
+ * an alternative {@code CronetProvider} implementation.
+ */
+ private static final String RES_KEY_CRONET_IMPL_CLASS = "CronetProviderClassName";
+
+ private static final String TAG = CronetProvider.class.getSimpleName();
+
+ protected final Context mContext;
+
+ protected CronetProvider(Context context) {
+ if (context == null) {
+ throw new IllegalArgumentException("Context must not be null");
+ }
+ mContext = context;
+ }
+
+ /**
+ * Creates and returns an instance of {@link CronetEngine.Builder}.
+ *
+ * NOTE: This class is for advanced users that want to select a particular
+ * Cronet implementation. Most users should simply use {@code new} {@link
+ * CronetEngine.Builder#CronetEngine.Builder(android.content.Context)}.
+ *
+ * @return {@code CronetEngine.Builder}.
+ * @throws IllegalStateException if the provider is not enabled (see {@link #isEnabled}.
+ */
+ public abstract CronetEngine.Builder createBuilder();
+
+ /**
+ * Returns the provider name. The well-know provider names include:
+ *
+ *
{@link #PROVIDER_NAME_APP_PACKAGED}
+ *
{@link #PROVIDER_NAME_FALLBACK}
+ *
+ *
+ * @return provider name.
+ */
+ public abstract String getName();
+
+ /**
+ * Returns the provider version. The version can be used to select the newest
+ * available provider if multiple providers are available.
+ *
+ * @return provider version.
+ */
+ public abstract String getVersion();
+
+ /**
+ * Returns whether the provider is enabled and can be used to instantiate the Cronet engine.
+ * A provider being out-of-date (older than the API) and needing updating is one potential
+ * reason it could be disabled. Please read the provider documentation for
+ * enablement procedure.
+ *
+ * @return {@code true} if the provider is enabled.
+ */
+ public abstract boolean isEnabled();
+
+ @Override
+ public String toString() {
+ return "["
+ + "class=" + getClass().getName() + ", "
+ + "name=" + getName() + ", "
+ + "version=" + getVersion() + ", "
+ + "enabled=" + isEnabled() + "]";
+ }
+
+ /**
+ * Name of the Java {@link CronetProvider} class.
+ */
+ private static final String JAVA_CRONET_PROVIDER_CLASS =
+ "org.chromium.net.impl.JavaCronetProvider";
+
+ /**
+ * Name of the native {@link CronetProvider} class.
+ */
+ private static final String NATIVE_CRONET_PROVIDER_CLASS =
+ "org.chromium.net.impl.NativeCronetProvider";
+
+ /**
+ * {@link CronetProvider} class that is packaged with Google Play Services.
+ */
+ private static final String PLAY_SERVICES_CRONET_PROVIDER_CLASS =
+ "com.google.android.gms.net.PlayServicesCronetProvider";
+
+ /**
+ * {@link CronetProvider} a deprecated class that may be packaged with
+ * some old versions of Google Play Services.
+ */
+ private static final String GMS_CORE_CRONET_PROVIDER_CLASS =
+ "com.google.android.gms.net.GmsCoreCronetProvider";
+
+ /**
+ * Returns an unmodifiable list of all available {@link CronetProvider}s.
+ * The providers are returned in no particular order. Some of the returned
+ * providers may be in a disabled state and should be enabled by the invoker.
+ * See {@link CronetProvider#isEnabled()}.
+ *
+ * @return the list of available providers.
+ */
+ public static List getAllProviders(Context context) {
+ // Use LinkedHashSet to preserve the order and eliminate duplicate providers.
+ Set providers = new LinkedHashSet<>();
+ addCronetProviderFromResourceFile(context, providers);
+ addCronetProviderImplByClassName(
+ context, PLAY_SERVICES_CRONET_PROVIDER_CLASS, providers, false);
+ addCronetProviderImplByClassName(context, GMS_CORE_CRONET_PROVIDER_CLASS, providers, false);
+ addCronetProviderImplByClassName(context, NATIVE_CRONET_PROVIDER_CLASS, providers, false);
+ addCronetProviderImplByClassName(context, JAVA_CRONET_PROVIDER_CLASS, providers, false);
+ return Collections.unmodifiableList(new ArrayList<>(providers));
+ }
+
+ /**
+ * Attempts to add a new provider referenced by the class name to a set.
+ *
+ * @param className the class name of the provider that should be instantiated.
+ * @param providers the set of providers to add the new provider to.
+ * @return {@code true} if the provider was added to the set; {@code false}
+ * if the provider couldn't be instantiated.
+ */
+ private static boolean addCronetProviderImplByClassName(
+ Context context, String className, Set providers, boolean logError) {
+ ClassLoader loader = context.getClassLoader();
+ try {
+ Class extends CronetProvider> providerClass =
+ loader.loadClass(className).asSubclass(CronetProvider.class);
+ Constructor extends CronetProvider> ctor =
+ providerClass.getConstructor(Context.class);
+ providers.add(ctor.newInstance(context));
+ return true;
+ } catch (InstantiationException e) {
+ logReflectiveOperationException(className, logError, e);
+ } catch (InvocationTargetException e) {
+ logReflectiveOperationException(className, logError, e);
+ } catch (NoSuchMethodException e) {
+ logReflectiveOperationException(className, logError, e);
+ } catch (IllegalAccessException e) {
+ logReflectiveOperationException(className, logError, e);
+ } catch (ClassNotFoundException e) {
+ logReflectiveOperationException(className, logError, e);
+ }
+ return false;
+ }
+
+ /**
+ * De-duplicates exception handling logic in {@link #addCronetProviderImplByClassName}.
+ * It should be removed when support of API Levels lower than 19 is deprecated.
+ */
+ private static void logReflectiveOperationException(
+ String className, boolean logError, Exception e) {
+ if (logError) {
+ Log.e(TAG, "Unable to load provider class: " + className, e);
+ } else {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG,
+ "Tried to load " + className + " provider class but it wasn't"
+ + " included in the app classpath");
+ }
+ }
+ }
+
+ /**
+ * Attempts to add a provider specified in the app resource file to a set.
+ *
+ * @param providers the set of providers to add the new provider to.
+ * @return {@code true} if the provider was added to the set; {@code false}
+ * if the app resources do not include the string with
+ * {@link #RES_KEY_CRONET_IMPL_CLASS} key.
+ * @throws RuntimeException if the provider cannot be found or instantiated.
+ */
+ private static boolean addCronetProviderFromResourceFile(
+ Context context, Set providers) {
+ int resId = context.getResources().getIdentifier(
+ RES_KEY_CRONET_IMPL_CLASS, "string", context.getPackageName());
+ // Resource not found
+ if (resId == 0) {
+ // The resource wasn't included in the app; therefore, there is nothing to add.
+ return false;
+ }
+ String className = context.getResources().getString(resId);
+
+ // If the resource specifies a well known provider, don't load it because
+ // there will be an attempt to load it anyways.
+ if (className == null || className.equals(PLAY_SERVICES_CRONET_PROVIDER_CLASS)
+ || className.equals(GMS_CORE_CRONET_PROVIDER_CLASS)
+ || className.equals(JAVA_CRONET_PROVIDER_CLASS)
+ || className.equals(NATIVE_CRONET_PROVIDER_CLASS)) {
+ return false;
+ }
+
+ if (!addCronetProviderImplByClassName(context, className, providers, true)) {
+ Log.e(TAG,
+ "Unable to instantiate Cronet implementation class " + className
+ + " that is listed as in the app string resource file under "
+ + RES_KEY_CRONET_IMPL_CLASS + " key");
+ }
+ return true;
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/ExperimentalBidirectionalStream.java b/src/components/cronet/android/api/src/org/chromium/net/ExperimentalBidirectionalStream.java
new file mode 100644
index 0000000000..d2c450dfed
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/ExperimentalBidirectionalStream.java
@@ -0,0 +1,101 @@
+// Copyright 2016 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.
+
+package org.chromium.net;
+
+/**
+ * {@link BidirectionalStream} that exposes experimental features. To obtain an
+ * instance of this class, cast a {@code BidirectionalStream} to this type. Every
+ * instance of {@code BidirectionalStream} can be cast to an instance of this class,
+ * as they are backed by the same implementation and hence perform identically.
+ * Instances of this class are not meant for general use, but instead only
+ * to access experimental features. Experimental features may be deprecated in the
+ * future. Use at your own risk.
+ *
+ * {@hide prototype}
+ */
+public abstract class ExperimentalBidirectionalStream extends BidirectionalStream {
+ /**
+ * {@link BidirectionalStream#Builder} that exposes experimental features. To obtain an
+ * instance of this class, cast a {@code BidirectionalStream.Builder} to this type. Every
+ * instance of {@code BidirectionalStream.Builder} can be cast to an instance of this class,
+ * as they are backed by the same implementation and hence perform identically.
+ * Instances of this class are not meant for general use, but instead only
+ * to access experimental features. Experimental features may be deprecated in the
+ * future. Use at your own risk.
+ */
+ public abstract static class Builder extends BidirectionalStream.Builder {
+ /**
+ * Associates the annotation object with this request. May add more than one.
+ * Passed through to a {@link RequestFinishedInfo.Listener},
+ * see {@link RequestFinishedInfo#getAnnotations}.
+ *
+ * @param annotation an object to pass on to the {@link RequestFinishedInfo.Listener} with a
+ * {@link RequestFinishedInfo}.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder addRequestAnnotation(Object annotation) {
+ return this;
+ }
+
+ /**
+ * Sets {@link android.net.TrafficStats} tag to use when accounting socket traffic caused by
+ * this request. See {@link android.net.TrafficStats} for more information. If no tag is
+ * set (e.g. this method isn't called), then Android accounts for the socket traffic caused
+ * by this request as if the tag value were set to 0.
+ *
+ * NOTE:Setting a tag disallows sharing of sockets with requests
+ * with other tags, which may adversely effect performance by prohibiting
+ * connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2
+ * and QUIC) will only be allowed if all requests have the same socket tag.
+ *
+ * @param tag the tag value used to when accounting for socket traffic caused by this
+ * request. Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used
+ * internally by system services like {@link android.app.DownloadManager} when
+ * performing traffic on behalf of an application.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setTrafficStatsTag(int tag) {
+ return this;
+ }
+
+ /**
+ * Sets specific UID to use when accounting socket traffic caused by this request. See
+ * {@link android.net.TrafficStats} for more information. Designed for use when performing
+ * an operation on behalf of another application. Caller must hold
+ * {@link android.Manifest.permission#MODIFY_NETWORK_ACCOUNTING} permission. By default
+ * traffic is attributed to UID of caller.
+ *
+ * NOTE:Setting a UID disallows sharing of sockets with requests
+ * with other UIDs, which may adversely effect performance by prohibiting
+ * connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2
+ * and QUIC) will only be allowed if all requests have the same UID set.
+ *
+ * @param uid the UID to attribute socket traffic caused by this request.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setTrafficStatsUid(int uid) {
+ return this;
+ }
+
+ // To support method chaining, override superclass methods to return an
+ // instance of this class instead of the parent.
+
+ @Override
+ public abstract Builder setHttpMethod(String method);
+
+ @Override
+ public abstract Builder addHeader(String header, String value);
+
+ @Override
+ public abstract Builder setPriority(int priority);
+
+ @Override
+ public abstract Builder delayRequestHeadersUntilFirstFlush(
+ boolean delayRequestHeadersUntilFirstFlush);
+
+ @Override
+ public abstract ExperimentalBidirectionalStream build();
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java b/src/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java
new file mode 100644
index 0000000000..3505e0cf49
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java
@@ -0,0 +1,413 @@
+// Copyright 2016 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.
+package org.chromium.net;
+
+import android.content.Context;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.io.IOException;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Date;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/**
+ * {@link CronetEngine} that exposes experimental features. To obtain an
+ * instance of this class, cast a {@code CronetEngine} to this type. Every
+ * instance of {@code CronetEngine} can be cast to an instance of this class,
+ * as they are backed by the same implementation and hence perform identically.
+ * Instances of this class are not meant for general use, but instead only
+ * to access experimental features. Experimental features may be deprecated in the
+ * future. Use at your own risk.
+ *
+ * {@hide since this class exposes experimental features that should be hidden.}
+ */
+public abstract class ExperimentalCronetEngine extends CronetEngine {
+ /**
+ * The value of a connection metric is unknown.
+ */
+ public static final int CONNECTION_METRIC_UNKNOWN = -1;
+
+ /**
+ * The estimate of the effective connection type is unknown.
+ *
+ * @see #getEffectiveConnectionType
+ */
+ public static final int EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0;
+
+ /**
+ * The device is offline.
+ *
+ * @see #getEffectiveConnectionType
+ */
+ public static final int EFFECTIVE_CONNECTION_TYPE_OFFLINE = 1;
+
+ /**
+ * The estimate of the effective connection type is slow 2G.
+ *
+ * @see #getEffectiveConnectionType
+ */
+ public static final int EFFECTIVE_CONNECTION_TYPE_SLOW_2G = 2;
+
+ /**
+ * The estimate of the effective connection type is 2G.
+ *
+ * @see #getEffectiveConnectionType
+ */
+ public static final int EFFECTIVE_CONNECTION_TYPE_2G = 3;
+
+ /**
+ * The estimate of the effective connection type is 3G.
+ *
+ * @see #getEffectiveConnectionType
+ */
+ public static final int EFFECTIVE_CONNECTION_TYPE_3G = 4;
+
+ /**
+ * The estimate of the effective connection type is 4G.
+ *
+ * @see #getEffectiveConnectionType
+ */
+ public static final int EFFECTIVE_CONNECTION_TYPE_4G = 5;
+
+ /**
+ * A version of {@link CronetEngine.Builder} that exposes experimental
+ * features. Instances of this class are not meant for general use, but
+ * instead only to access experimental features. Experimental features
+ * may be deprecated in the future. Use at your own risk.
+ */
+ public static class Builder extends CronetEngine.Builder {
+ /**
+ * Constructs a {@link Builder} object that facilitates creating a
+ * {@link CronetEngine}. The default configuration enables HTTP/2 and
+ * disables QUIC, SDCH and the HTTP cache.
+ *
+ * @param context Android {@link Context}, which is used by
+ * {@link Builder} to retrieve the application
+ * context. A reference to only the application
+ * context will be kept, so as to avoid extending
+ * the lifetime of {@code context} unnecessarily.
+ */
+ public Builder(Context context) {
+ super(context);
+ }
+
+ /**
+ * Constructs {@link Builder} with a given delegate that provides the actual implementation
+ * of the {@code Builder} methods. This constructor is used only by the internal
+ * implementation.
+ *
+ * @param builderDelegate delegate that provides the actual implementation.
+ *
+ * {@hide}
+ */
+ public Builder(ICronetEngineBuilder builderDelegate) {
+ super(builderDelegate);
+ }
+
+ /**
+ * Enables the network quality estimator, which collects and reports
+ * measurements of round trip time (RTT) and downstream throughput at
+ * various layers of the network stack. After enabling the estimator,
+ * listeners of RTT and throughput can be added with
+ * {@link #addRttListener} and {@link #addThroughputListener} and
+ * removed with {@link #removeRttListener} and
+ * {@link #removeThroughputListener}. The estimator uses memory and CPU
+ * only when enabled.
+ * @param value {@code true} to enable network quality estimator,
+ * {@code false} to disable.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder enableNetworkQualityEstimator(boolean value) {
+ mBuilderDelegate.enableNetworkQualityEstimator(value);
+ return this;
+ }
+
+ /**
+ * Sets experimental options to be used in Cronet.
+ *
+ * @param options JSON formatted experimental options.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setExperimentalOptions(String options) {
+ mBuilderDelegate.setExperimentalOptions(options);
+ return this;
+ }
+
+ /**
+ * Sets the thread priority of Cronet's internal thread.
+ *
+ * @param priority the thread priority of Cronet's internal thread.
+ * A Linux priority level, from -20 for highest scheduling
+ * priority to 19 for lowest scheduling priority. For more
+ * information on values, see
+ * {@link android.os.Process#setThreadPriority(int, int)} and
+ * {@link android.os.Process#THREAD_PRIORITY_DEFAULT
+ * THREAD_PRIORITY_*} values.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setThreadPriority(int priority) {
+ mBuilderDelegate.setThreadPriority(priority);
+ return this;
+ }
+
+ /**
+ * Returns delegate, only for testing.
+ * @hide
+ */
+ @VisibleForTesting
+ public ICronetEngineBuilder getBuilderDelegate() {
+ return mBuilderDelegate;
+ }
+
+ // To support method chaining, override superclass methods to return an
+ // instance of this class instead of the parent.
+
+ @Override
+ public Builder setUserAgent(String userAgent) {
+ super.setUserAgent(userAgent);
+ return this;
+ }
+
+ @Override
+ public Builder setStoragePath(String value) {
+ super.setStoragePath(value);
+ return this;
+ }
+
+ @Override
+ public Builder setLibraryLoader(LibraryLoader loader) {
+ super.setLibraryLoader(loader);
+ return this;
+ }
+
+ @Override
+ public Builder enableQuic(boolean value) {
+ super.enableQuic(value);
+ return this;
+ }
+
+ @Override
+ public Builder enableHttp2(boolean value) {
+ super.enableHttp2(value);
+ return this;
+ }
+
+ @Override
+ public Builder enableSdch(boolean value) {
+ return this;
+ }
+
+ @Override
+ public Builder enableHttpCache(int cacheMode, long maxSize) {
+ super.enableHttpCache(cacheMode, maxSize);
+ return this;
+ }
+
+ @Override
+ public Builder addQuicHint(String host, int port, int alternatePort) {
+ super.addQuicHint(host, port, alternatePort);
+ return this;
+ }
+
+ @Override
+ public Builder addPublicKeyPins(String hostName, Set pinsSha256,
+ boolean includeSubdomains, Date expirationDate) {
+ super.addPublicKeyPins(hostName, pinsSha256, includeSubdomains, expirationDate);
+ return this;
+ }
+
+ @Override
+ public Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean value) {
+ super.enablePublicKeyPinningBypassForLocalTrustAnchors(value);
+ return this;
+ }
+
+ @Override
+ public ExperimentalCronetEngine build() {
+ return mBuilderDelegate.build();
+ }
+ }
+
+ /**
+ * Creates a builder for {@link BidirectionalStream} objects. All callbacks for
+ * generated {@code BidirectionalStream} objects will be invoked on
+ * {@code executor}. {@code executor} must not run tasks on the
+ * current thread, otherwise the networking operations may block and exceptions
+ * may be thrown at shutdown time.
+ *
+ * @param url URL for the generated streams.
+ * @param callback the {@link BidirectionalStream.Callback} object that gets invoked upon
+ * different events occurring.
+ * @param executor the {@link Executor} on which {@code callback} methods will be invoked.
+ *
+ * @return the created builder.
+ */
+ public abstract ExperimentalBidirectionalStream.Builder newBidirectionalStreamBuilder(
+ String url, BidirectionalStream.Callback callback, Executor executor);
+
+ @Override
+ public abstract ExperimentalUrlRequest.Builder newUrlRequestBuilder(
+ String url, UrlRequest.Callback callback, Executor executor);
+
+ /**
+ * Starts NetLog logging to a specified directory with a bounded size. The NetLog will contain
+ * events emitted by all live CronetEngines. The NetLog is useful for debugging.
+ * Once logging has stopped {@link #stopNetLog}, the data will be written
+ * to netlog.json in {@code dirPath}. If logging is interrupted, you can
+ * stitch the files found in .inprogress subdirectory manually using:
+ * https://chromium.googlesource.com/chromium/src/+/main/net/tools/stitch_net_log_files.py.
+ * The log can be viewed using a Chrome browser navigated to chrome://net-internals/#import.
+ * @param dirPath the directory where the netlog.json file will be created. dirPath must
+ * already exist. NetLog files must not exist in the directory. If actively
+ * logging, this method is ignored.
+ * @param logAll {@code true} to include basic events, user cookies,
+ * credentials and all transferred bytes in the log. This option presents a
+ * privacy risk, since it exposes the user's credentials, and should only be
+ * used with the user's consent and in situations where the log won't be public.
+ * {@code false} to just include basic events.
+ * @param maxSize the maximum total disk space in bytes that should be used by NetLog. Actual
+ * disk space usage may exceed this limit slightly.
+ */
+ public void startNetLogToDisk(String dirPath, boolean logAll, int maxSize) {}
+
+ /**
+ * Returns an estimate of the effective connection type computed by the network quality
+ * estimator. Call {@link Builder#enableNetworkQualityEstimator} to begin computing this
+ * value.
+ *
+ * @return the estimated connection type. The returned value is one of
+ * {@link #EFFECTIVE_CONNECTION_TYPE_UNKNOWN EFFECTIVE_CONNECTION_TYPE_* }.
+ */
+ public int getEffectiveConnectionType() {
+ return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+ }
+
+ /**
+ * Configures the network quality estimator for testing. This must be called
+ * before round trip time and throughput listeners are added, and after the
+ * network quality estimator has been enabled.
+ * @param useLocalHostRequests include requests to localhost in estimates.
+ * @param useSmallerResponses include small responses in throughput estimates.
+ * @param disableOfflineCheck when set to true, disables the device offline checks when
+ * computing the effective connection type or when writing the prefs.
+ */
+ public void configureNetworkQualityEstimatorForTesting(boolean useLocalHostRequests,
+ boolean useSmallerResponses, boolean disableOfflineCheck) {}
+
+ /**
+ * Registers a listener that gets called whenever the network quality
+ * estimator witnesses a sample round trip time. This must be called
+ * after {@link Builder#enableNetworkQualityEstimator}, and with throw an
+ * exception otherwise. Round trip times may be recorded at various layers
+ * of the network stack, including TCP, QUIC, and at the URL request layer.
+ * The listener is called on the {@link java.util.concurrent.Executor} that
+ * is passed to {@link Builder#enableNetworkQualityEstimator}.
+ * @param listener the listener of round trip times.
+ */
+ public void addRttListener(NetworkQualityRttListener listener) {}
+
+ /**
+ * Removes a listener of round trip times if previously registered with
+ * {@link #addRttListener}. This should be called after a
+ * {@link NetworkQualityRttListener} is added in order to stop receiving
+ * observations.
+ * @param listener the listener of round trip times.
+ */
+ public void removeRttListener(NetworkQualityRttListener listener) {}
+
+ /**
+ * Registers a listener that gets called whenever the network quality
+ * estimator witnesses a sample throughput measurement. This must be called
+ * after {@link Builder#enableNetworkQualityEstimator}. Throughput observations
+ * are computed by measuring bytes read over the active network interface
+ * at times when at least one URL response is being received. The listener
+ * is called on the {@link java.util.concurrent.Executor} that is passed to
+ * {@link Builder#enableNetworkQualityEstimator}.
+ * @param listener the listener of throughput.
+ */
+ public void addThroughputListener(NetworkQualityThroughputListener listener) {}
+
+ /**
+ * Removes a listener of throughput. This should be called after a
+ * {@link NetworkQualityThroughputListener} is added with
+ * {@link #addThroughputListener} in order to stop receiving observations.
+ * @param listener the listener of throughput.
+ */
+ public void removeThroughputListener(NetworkQualityThroughputListener listener) {}
+
+ /**
+ * Establishes a new connection to the resource specified by the {@link URL} {@code url}
+ * using the given proxy.
+ *
+ * Note: Cronet's {@link java.net.HttpURLConnection} implementation is subject to certain
+ * limitations, see {@link #createURLStreamHandlerFactory} for details.
+ *
+ * @param url URL of resource to connect to.
+ * @param proxy proxy to use when establishing connection.
+ * @return an {@link java.net.HttpURLConnection} instance implemented by this CronetEngine.
+ * @throws IOException if an error occurs while opening the connection.
+ */
+ // TODO(pauljensen): Expose once implemented, http://crbug.com/418111
+ public URLConnection openConnection(URL url, Proxy proxy) throws IOException {
+ return url.openConnection(proxy);
+ }
+
+ /**
+ * Registers a listener that gets called after the end of each request with the request info.
+ *
+ *
The listener is called on an {@link java.util.concurrent.Executor} provided by the
+ * listener.
+ *
+ * @param listener the listener for finished requests.
+ */
+ public void addRequestFinishedListener(RequestFinishedInfo.Listener listener) {}
+
+ /**
+ * Removes a finished request listener.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeRequestFinishedListener(RequestFinishedInfo.Listener listener) {}
+
+ /**
+ * Returns the HTTP RTT estimate (in milliseconds) computed by the network
+ * quality estimator. Set to {@link #CONNECTION_METRIC_UNKNOWN} if the value
+ * is unavailable. This must be called after
+ * {@link Builder#enableNetworkQualityEstimator}, and will throw an
+ * exception otherwise.
+ * @return Estimate of the HTTP RTT in milliseconds.
+ */
+ public int getHttpRttMs() {
+ return CONNECTION_METRIC_UNKNOWN;
+ }
+
+ /**
+ * Returns the transport RTT estimate (in milliseconds) computed by the
+ * network quality estimator. Set to {@link #CONNECTION_METRIC_UNKNOWN} if
+ * the value is unavailable. This must be called after
+ * {@link Builder#enableNetworkQualityEstimator}, and will throw an
+ * exception otherwise.
+ * @return Estimate of the transport RTT in milliseconds.
+ */
+ public int getTransportRttMs() {
+ return CONNECTION_METRIC_UNKNOWN;
+ }
+
+ /**
+ * Returns the downstream throughput estimate (in kilobits per second)
+ * computed by the network quality estimator. Set to
+ * {@link #CONNECTION_METRIC_UNKNOWN} if the value is
+ * unavailable. This must be called after
+ * {@link Builder#enableNetworkQualityEstimator}, and will
+ * throw an exception otherwise.
+ * @return Estimate of the downstream throughput in kilobits per second.
+ */
+ public int getDownstreamThroughputKbps() {
+ return CONNECTION_METRIC_UNKNOWN;
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/ExperimentalUrlRequest.java b/src/components/cronet/android/api/src/org/chromium/net/ExperimentalUrlRequest.java
new file mode 100644
index 0000000000..220986bdea
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/ExperimentalUrlRequest.java
@@ -0,0 +1,162 @@
+// Copyright 2016 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.
+package org.chromium.net;
+
+import java.util.concurrent.Executor;
+
+/**
+ * {@link UrlRequest} that exposes experimental features. To obtain an
+ * instance of this class, cast a {@code UrlRequest} to this type. Every
+ * instance of {@code UrlRequest} can be cast to an instance of this class,
+ * as they are backed by the same implementation and hence perform identically.
+ * Instances of this class are not meant for general use, but instead only
+ * to access experimental features. Experimental features may be deprecated in the
+ * future. Use at your own risk.
+ *
+ * {@hide since this class exposes experimental features that should be hidden}.
+ */
+public abstract class ExperimentalUrlRequest extends UrlRequest {
+ /**
+ * {@link UrlRequest#Builder} that exposes experimental features. To obtain an
+ * instance of this class, cast a {@code UrlRequest.Builder} to this type. Every
+ * instance of {@code UrlRequest.Builder} can be cast to an instance of this class,
+ * as they are backed by the same implementation and hence perform identically.
+ * Instances of this class are not meant for general use, but instead only
+ * to access experimental features. Experimental features may be deprecated in the
+ * future. Use at your own risk.
+ */
+ public abstract static class Builder extends UrlRequest.Builder {
+ /**
+ * Disables connection migration for the request if enabled for
+ * the session.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder disableConnectionMigration() {
+ return this;
+ }
+
+ /**
+ * Associates the annotation object with this request. May add more than one.
+ * Passed through to a {@link RequestFinishedInfo.Listener},
+ * see {@link RequestFinishedInfo#getAnnotations}.
+ *
+ * @param annotation an object to pass on to the {@link RequestFinishedInfo.Listener} with a
+ * {@link RequestFinishedInfo}.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder addRequestAnnotation(Object annotation) {
+ return this;
+ }
+
+ /**
+ * Sets {@link android.net.TrafficStats} tag to use when accounting socket traffic caused by
+ * this request. See {@link android.net.TrafficStats} for more information. If no tag is
+ * set (e.g. this method isn't called), then Android accounts for the socket traffic caused
+ * by this request as if the tag value were set to 0.
+ *
+ * NOTE:Setting a tag disallows sharing of sockets with requests
+ * with other tags, which may adversely effect performance by prohibiting
+ * connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2
+ * and QUIC) will only be allowed if all requests have the same socket tag.
+ *
+ * @param tag the tag value used to when accounting for socket traffic caused by this
+ * request. Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used
+ * internally by system services like {@link android.app.DownloadManager} when
+ * performing traffic on behalf of an application.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setTrafficStatsTag(int tag) {
+ return this;
+ }
+
+ /**
+ * Sets specific UID to use when accounting socket traffic caused by this request. See
+ * {@link android.net.TrafficStats} for more information. Designed for use when performing
+ * an operation on behalf of another application. Caller must hold
+ * {@link android.Manifest.permission#MODIFY_NETWORK_ACCOUNTING} permission. By default
+ * traffic is attributed to UID of caller.
+ *
+ * NOTE:Setting a UID disallows sharing of sockets with requests
+ * with other UIDs, which may adversely effect performance by prohibiting
+ * connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2
+ * and QUIC) will only be allowed if all requests have the same UID set.
+ *
+ * @param uid the UID to attribute socket traffic caused by this request.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setTrafficStatsUid(int uid) {
+ return this;
+ }
+
+ /**
+ * Sets a listener that gets invoked after {@link Callback#onCanceled onCanceled()},
+ * {@link Callback#onFailed onFailed()} or {@link Callback#onSucceeded onSucceeded()}
+ * return.
+ *
+ *
The listener is invoked with the request finished info on an
+ * {@link java.util.concurrent.Executor} provided by
+ * {@link RequestFinishedInfo.Listener#getExecutor getExecutor()}.
+ *
+ * @param listener the listener for finished requests.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setRequestFinishedListener(RequestFinishedInfo.Listener listener) {
+ return this;
+ }
+
+ /**
+ * Default request idempotency, only enable 0-RTT for safe HTTP methods. Passed to {@link
+ * #setIdempotency}.
+ */
+ public static final int DEFAULT_IDEMPOTENCY = 0;
+
+ /**
+ * Request is idempotent. Passed to {@link #setIdempotency}.
+ */
+ public static final int IDEMPOTENT = 1;
+
+ /**
+ * Request is not idempotent. Passed to {@link #setIdempotency}.
+ */
+ public static final int NOT_IDEMPOTENT = 2;
+
+ /**
+ * Sets idempotency of the request which should be one of the {@link #DEFAULT_IDEMPOTENCY
+ * IDEMPOTENT NOT_IDEMPOTENT} values. The default idempotency indicates that 0-RTT is only
+ * enabled for safe HTTP methods (GET, HEAD, OPTIONS, and TRACE).
+ *
+ * @param idempotency idempotency of the request which should be one of the {@link
+ * #DEFAULT_IDEMPOTENCY IDEMPOTENT NOT_IDEMPOTENT} values.
+ * @return the builder to facilitate chaining.
+ */
+ public Builder setIdempotency(int idempotency) {
+ return this;
+ }
+
+ // To support method chaining, override superclass methods to return an
+ // instance of this class instead of the parent.
+
+ @Override
+ public abstract Builder setHttpMethod(String method);
+
+ @Override
+ public abstract Builder addHeader(String header, String value);
+
+ @Override
+ public abstract Builder disableCache();
+
+ @Override
+ public abstract Builder setPriority(int priority);
+
+ @Override
+ public abstract Builder setUploadDataProvider(
+ UploadDataProvider uploadDataProvider, Executor executor);
+
+ @Override
+ public abstract Builder allowDirectExecutor();
+
+ @Override
+ public abstract ExperimentalUrlRequest build();
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java b/src/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java
new file mode 100644
index 0000000000..1f6694d4cc
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java
@@ -0,0 +1,54 @@
+// Copyright 2016 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.
+package org.chromium.net;
+
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * Defines methods that the actual implementation of {@link CronetEngine.Builder} has to implement.
+ * {@code CronetEngine.Builder} uses this interface to delegate the calls.
+ * For the documentation of individual methods, please see the identically named methods in
+ * {@link org.chromium.net.CronetEngine.Builder} and
+ * {@link org.chromium.net.ExperimentalCronetEngine.Builder}.
+ *
+ * {@hide internal class}
+ */
+public abstract class ICronetEngineBuilder {
+ // Public API methods.
+ public abstract ICronetEngineBuilder addPublicKeyPins(String hostName, Set pinsSha256,
+ boolean includeSubdomains, Date expirationDate);
+ public abstract ICronetEngineBuilder addQuicHint(String host, int port, int alternatePort);
+ public abstract ICronetEngineBuilder enableHttp2(boolean value);
+ public abstract ICronetEngineBuilder enableHttpCache(int cacheMode, long maxSize);
+ public abstract ICronetEngineBuilder enablePublicKeyPinningBypassForLocalTrustAnchors(
+ boolean value);
+ public abstract ICronetEngineBuilder enableQuic(boolean value);
+ public abstract ICronetEngineBuilder enableSdch(boolean value);
+ public ICronetEngineBuilder enableBrotli(boolean value) {
+ // Do nothing for older implementations.
+ return this;
+ }
+ public abstract ICronetEngineBuilder setExperimentalOptions(String options);
+ public abstract ICronetEngineBuilder setLibraryLoader(
+ CronetEngine.Builder.LibraryLoader loader);
+ public abstract ICronetEngineBuilder setStoragePath(String value);
+ public abstract ICronetEngineBuilder setUserAgent(String userAgent);
+ public abstract String getDefaultUserAgent();
+ public abstract ExperimentalCronetEngine build();
+
+ // Experimental API methods.
+ //
+ // Note: all experimental API methods should have default implementation. This will allow
+ // removing the experimental methods from the implementation layer without breaking
+ // the client.
+
+ public ICronetEngineBuilder enableNetworkQualityEstimator(boolean value) {
+ return this;
+ }
+
+ public ICronetEngineBuilder setThreadPriority(int priority) {
+ return this;
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/InlineExecutionProhibitedException.java b/src/components/cronet/android/api/src/org/chromium/net/InlineExecutionProhibitedException.java
new file mode 100644
index 0000000000..ec67202350
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/InlineExecutionProhibitedException.java
@@ -0,0 +1,18 @@
+// Copyright 2016 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.
+
+package org.chromium.net;
+
+import java.util.concurrent.RejectedExecutionException;
+
+/**
+ * Thrown when an executor runs a submitted runnable inline in {@link
+ * java.util.concurrent.Executor#execute(Runnable)} and {@link
+ * UrlRequest.Builder#allowDirectExecutor} was not called.
+ */
+public final class InlineExecutionProhibitedException extends RejectedExecutionException {
+ public InlineExecutionProhibitedException() {
+ super("Inline execution is prohibited for this request");
+ }
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/NetworkException.java b/src/components/cronet/android/api/src/org/chromium/net/NetworkException.java
new file mode 100644
index 0000000000..f93a17aa36
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/NetworkException.java
@@ -0,0 +1,111 @@
+// Copyright 2016 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.
+
+package org.chromium.net;
+
+/**
+ * Exception passed to {@link UrlRequest.Callback#onFailed UrlRequest.Callback.onFailed()} when
+ * Cronet fails to process a network request. In this case {@link #getErrorCode} and
+ * {@link #getCronetInternalErrorCode} can be used to get more information about the specific
+ * type of failure. If {@link #getErrorCode} returns {@link #ERROR_QUIC_PROTOCOL_FAILED},
+ * this exception can be cast to a {@link QuicException} which can provide further details.
+ */
+public abstract class NetworkException extends CronetException {
+ /**
+ * Error code indicating the host being sent the request could not be resolved to an IP address.
+ */
+ public static final int ERROR_HOSTNAME_NOT_RESOLVED = 1;
+ /**
+ * Error code indicating the device was not connected to any network.
+ */
+ public static final int ERROR_INTERNET_DISCONNECTED = 2;
+ /**
+ * Error code indicating that as the request was processed the network configuration changed.
+ * When {@link #getErrorCode} returns this code, this exception may be cast to
+ * {@link QuicException} for more information if
+ * QUIC protocol is used.
+ */
+ public static final int ERROR_NETWORK_CHANGED = 3;
+ /**
+ * Error code indicating a timeout expired. Timeouts expiring while attempting to connect will
+ * be reported as the more specific {@link #ERROR_CONNECTION_TIMED_OUT}.
+ */
+ public static final int ERROR_TIMED_OUT = 4;
+ /**
+ * Error code indicating the connection was closed unexpectedly.
+ */
+ public static final int ERROR_CONNECTION_CLOSED = 5;
+ /**
+ * Error code indicating the connection attempt timed out.
+ */
+ public static final int ERROR_CONNECTION_TIMED_OUT = 6;
+ /**
+ * Error code indicating the connection attempt was refused.
+ */
+ public static final int ERROR_CONNECTION_REFUSED = 7;
+ /**
+ * Error code indicating the connection was unexpectedly reset.
+ */
+ public static final int ERROR_CONNECTION_RESET = 8;
+ /**
+ * Error code indicating the IP address being contacted is unreachable, meaning there is no
+ * route to the specified host or network.
+ */
+ public static final int ERROR_ADDRESS_UNREACHABLE = 9;
+ /**
+ * Error code indicating an error related to the
+ * QUIC protocol. When {@link #getErrorCode} returns this code, this exception can be cast
+ * to {@link QuicException} for more information.
+ */
+ public static final int ERROR_QUIC_PROTOCOL_FAILED = 10;
+ /**
+ * Error code indicating another type of error was encountered.
+ * {@link #getCronetInternalErrorCode} can be consulted to get a more specific cause.
+ */
+ public static final int ERROR_OTHER = 11;
+
+ /**
+ * Constructs an exception that is caused by a network error.
+ *
+ * @param message explanation of failure.
+ * @param cause the cause (which is saved for later retrieval by the {@link
+ * java.io.IOException#getCause getCause()} method). A null value is permitted, and
+ * indicates that the cause is nonexistent or unknown.
+ */
+ protected NetworkException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Returns error code, one of {@link #ERROR_HOSTNAME_NOT_RESOLVED ERROR_*}.
+ *
+ * @return error code, one of {@link #ERROR_HOSTNAME_NOT_RESOLVED ERROR_*}.
+ */
+ public abstract int getErrorCode();
+
+ /**
+ * Returns a Cronet internal error code. This may provide more specific error
+ * diagnosis than {@link #getErrorCode}, but the constant values are not exposed to Java and
+ * may change over time. See
+ *
+ * here for the lastest list of values.
+ *
+ * @return Cronet internal error code.
+ */
+ public abstract int getCronetInternalErrorCode();
+
+ /**
+ * Returns {@code true} if retrying this request right away might succeed, {@code false}
+ * otherwise. For example returns {@code true} when {@link #getErrorCode} returns
+ * {@link #ERROR_NETWORK_CHANGED} because trying the request might succeed using the new
+ * network configuration, but {@code false} when {@code getErrorCode()} returns
+ * {@link #ERROR_INTERNET_DISCONNECTED} because retrying the request right away will
+ * encounter the same failure (instead retrying should be delayed until device regains
+ * network connectivity).
+ *
+ * @return {@code true} if retrying this request right away might succeed, {@code false}
+ * otherwise.
+ */
+ public abstract boolean immediatelyRetryable();
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/NetworkQualityRttListener.java b/src/components/cronet/android/api/src/org/chromium/net/NetworkQualityRttListener.java
new file mode 100644
index 0000000000..c6705a92b1
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/NetworkQualityRttListener.java
@@ -0,0 +1,44 @@
+// 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.
+
+package org.chromium.net;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Watches observations of various round trip times (RTTs) at various layers of
+ * the network stack. These include RTT estimates by QUIC and TCP, as well as
+ * the time between when a URL request is sent and when the first byte of the
+ * response is received.
+ * {@hide} as it's a prototype.
+ */
+public abstract class NetworkQualityRttListener {
+ /**
+ * The executor on which this listener will be notified. Set as a final
+ * field, so it can be safely accessed across threads.
+ */
+ private final Executor mExecutor;
+
+ /**
+ * @param executor The executor on which the observations are reported.
+ */
+ public NetworkQualityRttListener(Executor executor) {
+ if (executor == null) {
+ throw new IllegalStateException("Executor must not be null");
+ }
+ mExecutor = executor;
+ }
+
+ public Executor getExecutor() {
+ return mExecutor;
+ }
+
+ /**
+ * Reports a new round trip time observation.
+ * @param rttMs the round trip time in milliseconds.
+ * @param whenMs milliseconds since the Epoch (January 1st 1970, 00:00:00.000).
+ * @param source the observation source from {@link NetworkQualityObservationSource}.
+ */
+ public abstract void onRttObservation(int rttMs, long whenMs, int source);
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/NetworkQualityThroughputListener.java b/src/components/cronet/android/api/src/org/chromium/net/NetworkQualityThroughputListener.java
new file mode 100644
index 0000000000..44caac8987
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/NetworkQualityThroughputListener.java
@@ -0,0 +1,42 @@
+// 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.
+
+package org.chromium.net;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Listener that is notified of throughput observations from the network quality
+ * estimator.
+ * {@hide} as it's a prototype.
+ */
+public abstract class NetworkQualityThroughputListener {
+ /**
+ * The executor on which this listener will be notified. Set as a final
+ * field, so it can be safely accessed across threads.
+ */
+ private final Executor mExecutor;
+
+ /**
+ * @param executor The executor on which the observations are reported.
+ */
+ public NetworkQualityThroughputListener(Executor executor) {
+ if (executor == null) {
+ throw new IllegalStateException("Executor must not be null");
+ }
+ mExecutor = executor;
+ }
+
+ public Executor getExecutor() {
+ return mExecutor;
+ }
+
+ /**
+ * Reports a new throughput observation.
+ * @param throughputKbps the downstream throughput in kilobits per second.
+ * @param whenMs milliseconds since the Epoch (January 1st 1970, 00:00:00.000).
+ * @param source the observation source from {@link NetworkQualityObservationSource}.
+ */
+ public abstract void onThroughputObservation(int throughputKbps, long whenMs, int source);
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/QuicException.java b/src/components/cronet/android/api/src/org/chromium/net/QuicException.java
new file mode 100644
index 0000000000..ccebb7cf76
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/QuicException.java
@@ -0,0 +1,35 @@
+// Copyright 2016 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.
+
+package org.chromium.net;
+
+/**
+ * Subclass of {@link NetworkException} which contains a detailed
+ * QUIC error code from
+ * QuicErrorCode. An instance of {@code QuicException} is passed to {@code onFailed} callbacks
+ * when the error code is {@link NetworkException#ERROR_QUIC_PROTOCOL_FAILED
+ * NetworkException.ERROR_QUIC_PROTOCOL_FAILED}.
+ */
+public abstract class QuicException extends NetworkException {
+ /**
+ * Constructs an exception that is caused by a QUIC protocol error.
+ *
+ * @param message explanation of failure.
+ * @param cause the cause (which is saved for later retrieval by the {@link
+ * java.io.IOException#getCause getCause()} method). A null value is permitted, and
+ * indicates that the cause is nonexistent or unknown.
+ */
+ protected QuicException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Returns the QUIC error code, which is a value
+ * from
+ * QuicErrorCode.
+ */
+ public abstract int getQuicDetailedErrorCode();
+}
diff --git a/src/components/cronet/android/api/src/org/chromium/net/RequestFinishedInfo.java b/src/components/cronet/android/api/src/org/chromium/net/RequestFinishedInfo.java
new file mode 100644
index 0000000000..7cceb76806
--- /dev/null
+++ b/src/components/cronet/android/api/src/org/chromium/net/RequestFinishedInfo.java
@@ -0,0 +1,320 @@
+// Copyright 2016 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.
+
+package org.chromium.net;
+
+import androidx.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.concurrent.Executor;
+
+/**
+ * Information about a finished request. Passed to {@link RequestFinishedInfo.Listener}.
+ *
+ * To associate the data with the original request, use
+ * {@link ExperimentalUrlRequest.Builder#addRequestAnnotation} or
+ * {@link ExperimentalBidirectionalStream.Builder#addRequestAnnotation} to add a unique identifier
+ * when creating the request, and call {@link #getAnnotations} when the {@link RequestFinishedInfo}
+ * is received to retrieve the identifier.
+ *
+ * {@hide} as it's a prototype.
+ */
+public abstract class RequestFinishedInfo {
+ /**
+ * Listens for finished requests for the purpose of collecting metrics.
+ *
+ * {@hide} as it's a prototype.
+ */
+ public abstract static class Listener {
+ private final Executor mExecutor;
+
+ public Listener(Executor executor) {
+ if (executor == null) {
+ throw new IllegalStateException("Executor must not be null");
+ }
+ mExecutor = executor;
+ }
+
+ /**
+ * Invoked with request info. Will be called in a task submitted to the
+ * {@link java.util.concurrent.Executor} returned by {@link #getExecutor}.
+ * @param requestInfo {@link RequestFinishedInfo} for finished request.
+ */
+ public abstract void onRequestFinished(RequestFinishedInfo requestInfo);
+
+ /**
+ * Returns this listener's executor. Can be called on any thread.
+ * @return this listener's {@link java.util.concurrent.Executor}
+ */
+ public Executor getExecutor() {
+ return mExecutor;
+ }
+ }
+
+ /**
+ * Metrics collected for a single request. Most of these metrics are timestamps for events
+ * during the lifetime of the request, which can be used to build a detailed timeline for
+ * investigating performance.
+ *
+ * Events happen in this order:
+ *
+ *
{@link #getRequestStart request start}
+ *
{@link #getDnsStart DNS start}
+ *
{@link #getDnsEnd DNS end}
+ *
{@link #getConnectStart connect start}
+ *
{@link #getSslStart SSL start}
+ *
{@link #getSslEnd SSL end}
+ *
{@link #getConnectEnd connect end}
+ *
{@link #getSendingStart sending start}
+ *
{@link #getSendingEnd sending end}
+ *
{@link #getResponseStart response start}
+ *
{@link #getRequestEnd request end}
+ *
+ *
+ * Start times are reported as the time when a request started blocking on event, not when the
+ * event actually occurred, with the exception of push start and end. If a metric is not
+ * meaningful or not available, including cases when a request finished before reaching that
+ * stage, start and end times will be {@code null}. If no time was spent blocking on an event,
+ * start and end will be the same time.
+ *
+ * If the system clock is adjusted during the request, some of the {@link java.util.Date} values
+ * might not match it. Timestamps are recorded using a clock that is guaranteed not to run
+ * backwards. All timestamps are correct relative to the system clock at the time of request
+ * start, and taking the difference between two timestamps will give the correct difference
+ * between the events. In order to preserve this property, timestamps for events other than
+ * request start are not guaranteed to match the system clock at the times they represent.
+ *
+ * Most timing metrics are taken from
+ * LoadTimingInfo,
+ * which holds the information for and
+ * .
+ *
+ * {@hide} as it's a prototype.
+ */
+ public abstract static class Metrics {
+ /**
+ * Returns time when the request started.
+ * @return {@link java.util.Date} representing when the native request actually started.
+ * This timestamp will match the system clock at the time it represents.
+ */
+ @Nullable
+ public abstract Date getRequestStart();
+
+ /**
+ * Returns time when DNS lookup started. This and {@link #getDnsEnd} will return non-null
+ * values regardless of whether the result came from a DNS server or the local cache.
+ * @return {@link java.util.Date} representing when DNS lookup started. {@code null} if the
+ * socket was reused (see {@link #getSocketReused}).
+ */
+ @Nullable
+ public abstract Date getDnsStart();
+
+ /**
+ * Returns time when DNS lookup finished. This and {@link #getDnsStart} will return non-null
+ * values regardless of whether the result came from a DNS server or the local cache.
+ * @return {@link java.util.Date} representing when DNS lookup finished. {@code null} if the
+ * socket was reused (see {@link #getSocketReused}).
+ */
+ @Nullable
+ public abstract Date getDnsEnd();
+
+ /**
+ * Returns time when connection establishment started.
+ * @return {@link java.util.Date} representing when connection establishment started,
+ * typically when DNS resolution finishes. {@code null} if the socket was reused (see
+ * {@link #getSocketReused}).
+ */
+ @Nullable
+ public abstract Date getConnectStart();
+
+ /**
+ * Returns time when connection establishment finished.
+ * @return {@link java.util.Date} representing when connection establishment finished,
+ * after TCP connection is established and, if using HTTPS, SSL handshake is completed.
+ * For QUIC 0-RTT, this represents the time of handshake confirmation and might happen
+ * later than {@link #getSendingStart}.
+ * {@code null} if the socket was reused (see {@link #getSocketReused}).
+ */
+ @Nullable
+ public abstract Date getConnectEnd();
+
+ /**
+ * Returns time when SSL handshake started. For QUIC, this will be the same time as
+ * {@link #getConnectStart}.
+ * @return {@link java.util.Date} representing when SSL handshake started. {@code null} if
+ * SSL is not used or if the socket was reused (see {@link #getSocketReused}).
+ */
+ @Nullable
+ public abstract Date getSslStart();
+
+ /**
+ * Returns time when SSL handshake finished. For QUIC, this will be the same time as
+ * {@link #getConnectEnd}.
+ * @return {@link java.util.Date} representing when SSL handshake finished. {@code null} if
+ * SSL is not used or if the socket was reused (see {@link #getSocketReused}).
+ */
+ @Nullable
+ public abstract Date getSslEnd();
+
+ /**
+ * Returns time when sending the request started.
+ * @return {@link java.util.Date} representing when sending HTTP request headers started.
+ */
+ @Nullable
+ public abstract Date getSendingStart();
+
+ /**
+ * Returns time when sending the request finished.
+ * @return {@link java.util.Date} representing when sending HTTP request body finished.
+ * (Sending request body happens after sending request headers.)
+ */
+ @Nullable
+ public abstract Date getSendingEnd();
+
+ /**
+ * Returns time when first byte of HTTP/2 server push was received.
+ * @return {@link java.util.Date} representing when the first byte of an HTTP/2 server push
+ * was received. {@code null} if server push is not used.
+ */
+ @Nullable
+ public abstract Date getPushStart();
+
+ /**
+ * Returns time when last byte of HTTP/2 server push was received.
+ * @return {@link java.util.Date} representing when the last byte of an HTTP/2 server push
+ * was received. {@code null} if server push is not used.
+ */
+ @Nullable
+ public abstract Date getPushEnd();
+
+ /**
+ * Returns time when the end of the response headers was received.
+ * @return {@link java.util.Date} representing when the end of the response headers was
+ * received.
+ */
+ @Nullable
+ public abstract Date getResponseStart();
+
+ /**
+ * Returns time when the request finished.
+ * @return {@link java.util.Date} representing when the request finished.
+ */
+ @Nullable
+ public abstract Date getRequestEnd();
+
+ /**
+ * Returns whether the socket was reused from a previous request. In HTTP/2 or QUIC, if
+ * streams are multiplexed in a single connection, returns {@code true} for all streams
+ * after the first.
+ * @return whether this request reused a socket from a previous request. When {@code true},
+ * DNS, connection, and SSL times will be {@code null}.
+ */
+ public abstract boolean getSocketReused();
+
+ /**
+ * Returns milliseconds between request initiation and first byte of response headers,
+ * or {@code null} if not collected.
+ * TODO(mgersh): Remove once new API works http://crbug.com/629194
+ * {@hide}
+ */
+ @Nullable
+ public abstract Long getTtfbMs();
+
+ /**
+ * Returns milliseconds between request initiation and finish,
+ * including a failure or cancellation, or {@code null} if not collected.
+ * TODO(mgersh): Remove once new API works http://crbug.com/629194
+ * {@hide}
+ */
+ @Nullable
+ public abstract Long getTotalTimeMs();
+
+ /**
+ * Returns total bytes sent over the network transport layer, or {@code null} if not
+ * collected.
+ */
+ @Nullable
+ public abstract Long getSentByteCount();
+
+ /**
+ * Returns total bytes received over the network transport layer, or {@code null} if not
+ * collected. Number of bytes does not include any previous redirects.
+ */
+ @Nullable
+ public abstract Long getReceivedByteCount();
+ }
+
+ /**
+ * Reason value indicating that the request succeeded. Returned from {@link #getFinishedReason}.
+ */
+ public static final int SUCCEEDED = 0;
+ /**
+ * Reason value indicating that the request failed or returned an error. Returned from
+ * {@link #getFinishedReason}.
+ */
+ public static final int FAILED = 1;
+ /**
+ * Reason value indicating that the request was canceled. Returned from
+ * {@link #getFinishedReason}.
+ */
+ public static final int CANCELED = 2;
+
+ /**
+ * Returns the request's original URL.
+ *
+ * @return the request's original URL
+ */
+ public abstract String getUrl();
+
+ /**
+ * Returns the objects that the caller has supplied when initiating the request, using
+ * {@link ExperimentalUrlRequest.Builder#addRequestAnnotation} or
+ * {@link ExperimentalBidirectionalStream.Builder#addRequestAnnotation}.
+ * Annotations can be used to associate a {@link RequestFinishedInfo} with the original request
+ * or type of request.
+ *
+ * @return annotations supplied when creating the request
+ */
+ public abstract Collection