diff --git a/src/components/cronet/android/cronet_library_loader.cc b/src/components/cronet/android/cronet_library_loader.cc index 2a7a261e98..d7168663b1 100644 --- a/src/components/cronet/android/cronet_library_loader.cc +++ b/src/components/cronet/android/cronet_library_loader.cc @@ -146,7 +146,8 @@ void PostTaskToInitThread(const base::Location& posted_from, g_init_task_executor->task_runner()->PostTask(posted_from, std::move(task)); } -void EnsureInitialized() { +void EnsureInitialized(const char* /*enable_features*/, + const char* /*disable_features*/) { if (g_init_task_executor) { // Ensure that init is done on the init thread. g_init_thread_init_done.Wait(); diff --git a/src/components/cronet/cronet_global_state.h b/src/components/cronet/cronet_global_state.h index 10003b0be1..a8f8b2b79c 100644 --- a/src/components/cronet/cronet_global_state.h +++ b/src/components/cronet/cronet_global_state.h @@ -31,7 +31,8 @@ void PostTaskToInitThread(const base::Location& posted_from, // or binding to an existing thread, to run initialization and process // network notifications on. The implementation must be thread-safe and // idempotent, and must complete initialization before returning. -void EnsureInitialized(); +void EnsureInitialized(const char* enable_features = nullptr, + const char* disable_features = nullptr); // Creates a proxy config service appropriate for this platform that fetches the // system proxy settings. Cronet will call this API only after a prior call diff --git a/src/components/cronet/cronet_global_state_stubs.cc b/src/components/cronet/cronet_global_state_stubs.cc index ff55b51348..0aab153bb2 100644 --- a/src/components/cronet/cronet_global_state_stubs.cc +++ b/src/components/cronet/cronet_global_state_stubs.cc @@ -21,14 +21,18 @@ namespace cronet { namespace { -scoped_refptr InitializeAndCreateTaskRunner() { +scoped_refptr InitializeAndCreateTaskRunner( + const char* enable_features, + const char* disable_features) { // Cronet tests sets AtExitManager as part of TestSuite, so statically linked // library is not allowed to set its own. #if !defined(CRONET_TESTS_IMPLEMENTATION) std::ignore = new base::AtExitManager; #endif - base::FeatureList::InitializeInstance(std::string(), std::string()); + base::FeatureList::InitializeInstance( + enable_features ? enable_features : "", + disable_features ? disable_features : ""); // Note that in component builds this ThreadPoolInstance will be shared with // the calling process, if it also depends on //base. In particular this means @@ -39,16 +43,19 @@ scoped_refptr InitializeAndCreateTaskRunner() { return base::ThreadPool::CreateSingleThreadTaskRunner({}); } -base::SingleThreadTaskRunner* InitTaskRunner() { +base::SingleThreadTaskRunner* InitTaskRunner( + const char* enable_features = nullptr, + const char* disable_features = nullptr) { static scoped_refptr init_task_runner = - InitializeAndCreateTaskRunner(); + InitializeAndCreateTaskRunner(enable_features, disable_features); return init_task_runner.get(); } } // namespace -void EnsureInitialized() { - std::ignore = InitTaskRunner(); +void EnsureInitialized(const char* enable_features, + const char* disable_features) { + std::ignore = InitTaskRunner(enable_features, disable_features); } bool OnInitThread() { diff --git a/src/components/cronet/native/engine.cc b/src/components/cronet/native/engine.cc index 8c110870a0..59d2254730 100644 --- a/src/components/cronet/native/engine.cc +++ b/src/components/cronet/native/engine.cc @@ -7,6 +7,7 @@ #include #include +#include "base/base_switches.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/files/file_path.h" @@ -102,6 +103,23 @@ Cronet_EngineImpl::~Cronet_EngineImpl() { Cronet_RESULT Cronet_EngineImpl::StartWithParams( Cronet_EngineParamsPtr params) { + absl::optional experimental_options = + URLRequestContextConfig::ParseExperimentalOptions( + params->experimental_options); + if (experimental_options) { + const base::Value* feature_list = + experimental_options->Find("feature_list"); + if (feature_list != nullptr && feature_list->is_dict()) { + const std::string* enable_features = + feature_list->GetDict().FindString(switches::kEnableFeatures); + const std::string* disable_features = + feature_list->GetDict().FindString(switches::kDisableFeatures); + cronet::EnsureInitialized( + enable_features ? enable_features->c_str() : nullptr, + disable_features ? disable_features->c_str() : nullptr); + } + } + cronet::EnsureInitialized(); base::AutoLock lock(lock_); diff --git a/src/components/cronet/url_request_context_config.cc b/src/components/cronet/url_request_context_config.cc index 8545d95d49..7ec27a7d4a 100644 --- a/src/components/cronet/url_request_context_config.cc +++ b/src/components/cronet/url_request_context_config.cc @@ -765,6 +765,15 @@ void URLRequestContextConfig::SetContextBuilderExperimentalOptions( continue; } // Handled in CronetContext::NetworkTasks::BuildDefaultURLRequestContext. + } else if (iter->first == "feature_list") { + if (!iter->second.is_dict()) { + LOG(ERROR) << "\"" << iter->first << "\" config params \"" + << iter->second << "\" is not a dictionary value"; + effective_experimental_options.Remove(iter->first); + continue; + } + // Already handled in Cronet_EngineImpl::StartWithParams. + // Only checks and reports errors here. } else { LOG(WARNING) << "Unrecognized Cronet experimental option \"" << iter->first << "\" with params \"" << iter->second; diff --git a/src/components/cronet/url_request_context_config.h b/src/components/cronet/url_request_context_config.h index 0b45f8fa98..d6d4ac8582 100644 --- a/src/components/cronet/url_request_context_config.h +++ b/src/components/cronet/url_request_context_config.h @@ -256,12 +256,14 @@ struct URLRequestContextConfig { // not specify for other targets. absl::optional network_thread_priority); + public: // Parses experimental options from their JSON format to the format used // internally. // Returns an empty optional if the operation was unsuccessful. static absl::optional ParseExperimentalOptions( std::string unparsed_experimental_options); + private: // Makes appropriate changes to settings in |this|. void SetContextConfigExperimentalOptions();