1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_CRONET_CRONET_CONTEXT_H_ 6 #define COMPONENTS_CRONET_CRONET_CONTEXT_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <string> 12 13 #include "base/containers/flat_map.h" 14 #include "base/containers/queue.h" 15 #include "base/functional/callback.h" 16 #include "base/memory/raw_ptr.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/task/sequenced_task_runner.h" 19 #include "base/threading/thread.h" 20 #include "base/threading/thread_checker.h" 21 #include "base/values.h" 22 #include "components/prefs/json_pref_store.h" 23 #include "net/base/network_change_notifier.h" 24 #include "net/base/network_handle.h" 25 #include "net/nqe/effective_connection_type.h" 26 #include "net/nqe/effective_connection_type_observer.h" 27 #include "net/nqe/network_quality_estimator.h" 28 #include "net/nqe/network_quality_observation_source.h" 29 #include "net/nqe/rtt_throughput_estimates_observer.h" 30 31 class PrefService; 32 33 namespace base { 34 class SingleThreadTaskRunner; 35 class TimeTicks; 36 } // namespace base 37 38 namespace net { 39 enum EffectiveConnectionType; 40 class ProxyConfigService; 41 class NetLog; 42 class URLRequestContext; 43 class URLRequestContextBuilder; 44 class URLRequestContextGetter; 45 class FileNetLogObserver; 46 } // namespace net 47 48 namespace cronet { 49 class CronetPrefsManager; 50 class TestUtil; 51 52 struct URLRequestContextConfig; 53 54 // Wrapper around net::URLRequestContext. 55 class CronetContext { 56 public: 57 // Callback implemented by CronetContext() caller and owned by 58 // CronetContext::NetworkTasks. 59 class Callback { 60 public: 61 virtual ~Callback() = default; 62 63 // Invoked on network thread when initialized. 64 virtual void OnInitNetworkThread() = 0; 65 66 // Invoked on network thread immediately prior to destruction. 67 virtual void OnDestroyNetworkThread() = 0; 68 69 // net::NetworkQualityEstimator::EffectiveConnectionTypeObserver forwarder. 70 virtual void OnEffectiveConnectionTypeChanged( 71 net::EffectiveConnectionType effective_connection_type) = 0; 72 73 // net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver 74 // forwarder. 75 virtual void OnRTTOrThroughputEstimatesComputed( 76 int32_t http_rtt_ms, 77 int32_t transport_rtt_ms, 78 int32_t downstream_throughput_kbps) = 0; 79 80 // net::NetworkQualityEstimator::RTTObserver forwarder. 81 virtual void OnRTTObservation( 82 int32_t rtt_ms, 83 int32_t timestamp_ms, 84 net::NetworkQualityObservationSource source) = 0; 85 86 // net::NetworkQualityEstimator::RTTObserver forwarder. 87 virtual void OnThroughputObservation( 88 int32_t throughput_kbps, 89 int32_t timestamp_ms, 90 net::NetworkQualityObservationSource source) = 0; 91 92 // Callback for StopNetLog() that signals that it is safe to access 93 // the NetLog files. 94 virtual void OnStopNetLogCompleted() = 0; 95 }; 96 97 // Constructs CronetContext using |context_config|. The |callback| 98 // is owned by |this| and is deleted on network thread. 99 // All |callback| methods are invoked on network thread. 100 // If the network_task_runner is not assigned, a network thread would be 101 // created for network tasks. Otherwise the tasks would be running on the 102 // assigned task runner. 103 CronetContext(std::unique_ptr<URLRequestContextConfig> context_config, 104 std::unique_ptr<Callback> callback, 105 scoped_refptr<base::SingleThreadTaskRunner> 106 network_task_runner = nullptr); 107 108 CronetContext(const CronetContext&) = delete; 109 CronetContext& operator=(const CronetContext&) = delete; 110 111 // Releases all resources for the request context and deletes the object. 112 // Blocks until network thread is destroyed after running all pending tasks. 113 virtual ~CronetContext(); 114 115 // Called on init thread to initialize URLRequestContext. 116 void InitRequestContextOnInitThread(); 117 118 // Posts a task that might depend on the context being initialized 119 // to the network thread. 120 void PostTaskToNetworkThread(const base::Location& posted_from, 121 base::OnceClosure callback); 122 123 // Returns true if running on network thread. 124 bool IsOnNetworkThread() const; 125 126 // Returns the net::URLRequestContext associated with `network`. 127 // kInvalidNetworkHandle represent the default context: this one will always 128 // be present and used whenever a requests doesn't specify a target network 129 // (currently the only possible behavior). 130 net::URLRequestContext* GetURLRequestContext( 131 net::handles::NetworkHandle network = 132 net::handles::kInvalidNetworkHandle); 133 134 // Returns a new instance of net::URLRequestContextGetter. 135 // The net::URLRequestContext and base::SingleThreadTaskRunner that 136 // net::URLRequestContextGetter returns are owned by `this`. 137 // The returned getter will always return the default context of `this`. 138 net::URLRequestContextGetter* CreateURLRequestContextGetter(); 139 140 // TODO(xunjieli): Keep only one version of StartNetLog(). 141 142 // Starts NetLog logging to file. This can be called on any thread. 143 // Return false if |file_name| cannot be opened. 144 bool StartNetLogToFile(const std::string& file_name, bool log_all); 145 146 // Starts NetLog logging to disk with a bounded amount of disk space. This 147 // can be called on any thread. 148 void StartNetLogToDisk(const std::string& dir_name, 149 bool log_all, 150 int max_size); 151 152 // Stops NetLog logging to file. This can be called on any thread. This will 153 // flush any remaining writes to disk. 154 void StopNetLog(); 155 156 void FlushWritePropertiesForTesting(); 157 158 // Destroys the URLRequestContext associated to `network` if `network` has 159 // disconnected and it has no pending URLRequests. This must be called on 160 // the network thread while destroying a CronetURLRequest as that might 161 // mark a URLRequestContext as eligible for destruction. 162 void MaybeDestroyURLRequestContext(net::handles::NetworkHandle network); 163 164 // Default net::LOAD flags used to create requests. 165 int default_load_flags() const; 166 167 // Configures the network quality estimator to observe requests to localhost, 168 // to use smaller responses when estimating throughput, and to disable the 169 // device offline checks when computing the effective connection type or when 170 // writing the prefs. This should only be used for testing. This can be 171 // called only after the network quality estimator has been enabled. 172 void ConfigureNetworkQualityEstimatorForTesting(bool use_local_host_requests, 173 bool use_smaller_responses, 174 bool disable_offline_check); 175 176 bool URLRequestContextExistsForTesting(net::handles::NetworkHandle network); 177 178 // Request that RTT and/or throughput observations should or should not be 179 // provided by the network quality estimator. 180 void ProvideRTTObservations(bool should); 181 void ProvideThroughputObservations(bool should); 182 bidi_stream_detect_broken_connection()183 bool bidi_stream_detect_broken_connection() const { 184 return bidi_stream_detect_broken_connection_; 185 } heartbeat_interval()186 base::TimeDelta heartbeat_interval() const { return heartbeat_interval_; } 187 188 // NetworkTasks performs tasks on the network thread and owns objects that 189 // live on the network thread. 190 class NetworkTasks : public net::EffectiveConnectionTypeObserver, 191 public net::RTTAndThroughputEstimatesObserver, 192 public net::NetworkQualityEstimator::RTTObserver, 193 public net::NetworkQualityEstimator::ThroughputObserver, 194 public net::NetworkChangeNotifier::NetworkObserver { 195 public: 196 // Invoked off the network thread. 197 // `listen_to_network_changes` is a temporary parameter to allow 198 // multi-network testing for the time being. 199 NetworkTasks(std::unique_ptr<URLRequestContextConfig> config, 200 std::unique_ptr<CronetContext::Callback> callback); 201 202 NetworkTasks(const NetworkTasks&) = delete; 203 NetworkTasks& operator=(const NetworkTasks&) = delete; 204 205 // Invoked on the network thread. 206 ~NetworkTasks() override; 207 208 // Initializes |context_| on the network thread. 209 void Initialize( 210 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, 211 scoped_refptr<base::SequencedTaskRunner> file_task_runner, 212 std::unique_ptr<net::ProxyConfigService> proxy_config_service); 213 214 // Runs a task that might depend on the context being initialized. 215 void RunTaskAfterContextInit( 216 base::OnceClosure task_to_run_after_context_init); 217 218 // Configures the network quality estimator to observe requests to 219 // localhost, to use smaller responses when estimating throughput, and to 220 // disable the device offline checks when computing the effective connection 221 // type or when writing the prefs. This should only be used for testing. 222 void ConfigureNetworkQualityEstimatorForTesting( 223 bool use_local_host_requests, 224 bool use_smaller_responses, 225 bool disable_offline_check); 226 227 void ProvideRTTObservations(bool should); 228 void ProvideThroughputObservations(bool should); 229 230 // net::NetworkQualityEstimator::EffectiveConnectionTypeObserver 231 // implementation. 232 void OnEffectiveConnectionTypeChanged( 233 net::EffectiveConnectionType effective_connection_type) override; 234 235 // net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver 236 // implementation. 237 void OnRTTOrThroughputEstimatesComputed( 238 base::TimeDelta http_rtt, 239 base::TimeDelta transport_rtt, 240 int32_t downstream_throughput_kbps) override; 241 242 // net::NetworkQualityEstimator::RTTObserver implementation. 243 void OnRTTObservation(int32_t rtt_ms, 244 const base::TimeTicks& timestamp, 245 net::NetworkQualityObservationSource source) override; 246 247 // net::NetworkQualityEstimator::ThroughputObserver implementation. 248 void OnThroughputObservation( 249 int32_t throughput_kbps, 250 const base::TimeTicks& timestamp, 251 net::NetworkQualityObservationSource source) override; 252 253 // net::NetworkChangeNotifier::NetworkObserver implementation. 254 void OnNetworkDisconnected(net::handles::NetworkHandle network) override; 255 void OnNetworkConnected(net::handles::NetworkHandle network) override; 256 void OnNetworkSoonToDisconnect( 257 net::handles::NetworkHandle network) override; 258 void OnNetworkMadeDefault(net::handles::NetworkHandle network) override; 259 260 net::URLRequestContext* GetURLRequestContext( 261 net::handles::NetworkHandle network); 262 263 // Same as StartNetLogToDisk. 264 void StartNetLogToBoundedFile(const std::string& dir_path, 265 bool include_socket_bytes, 266 int size); 267 268 // Same as StartNetLogToFile, but called only on the network thread. 269 void StartNetLog(const base::FilePath& file_path, 270 bool include_socket_bytes); 271 272 // Stops NetLog logging. 273 void StopNetLog(); 274 275 void MaybeDestroyURLRequestContext(net::handles::NetworkHandle network); 276 277 // Callback for StopObserving() that unblocks the client thread and 278 // signals that it is safe to access the NetLog files. 279 void StopNetLogCompleted(); 280 281 // Initializes Network Quality Estimator (NQE) prefs manager on network 282 // thread. 283 void InitializeNQEPrefs() const; 284 285 void SpawnNetworkBoundURLRequestContextForTesting( 286 net::handles::NetworkHandle network); 287 bool URLRequestContextExistsForTesting(net::handles::NetworkHandle network); 288 289 private: 290 friend class TestUtil; 291 base::Value GetNetLogInfo() const; 292 293 // Configures `context_builder` with the settings shared between default 294 // context and network bound contexts. 295 void SetSharedURLRequestContextBuilderConfig( 296 net::URLRequestContextBuilder* context_builder); 297 298 // Configures `context` with the settings shared between default context 299 // and network bound contexts. 300 void SetSharedURLRequestContextConfig(net::URLRequestContext* context); 301 302 // Builds a URLRequestContext specifically bound to `network`. 303 std::unique_ptr<net::URLRequestContext> BuildNetworkBoundURLRequestContext( 304 net::handles::NetworkHandle network); 305 306 // Builds a URLRequestContext to be used a default context for `this`. 307 // `proxy_config_service` is injected as it currently cannot be built on the 308 // network thread. 309 std::unique_ptr<net::URLRequestContext> BuildDefaultURLRequestContext( 310 std::unique_ptr<net::ProxyConfigService> proxy_config_service); 311 312 std::unique_ptr<net::FileNetLogObserver> net_log_file_observer_; 313 314 // A network quality estimator. This member variable has to be destroyed 315 // after destroying |cronet_prefs_manager_|, which owns 316 // NetworkQualityPrefsManager that weakly references 317 // |network_quality_estimator_|. 318 std::unique_ptr<net::NetworkQualityEstimator> network_quality_estimator_; 319 320 // Manages the PrefService and all associated persistence managers 321 // such as NetworkQualityPrefsManager, HostCachePersistenceManager, etc. 322 // It should be destroyed before |network_quality_estimator_| and 323 // after |context_|. 324 std::unique_ptr<CronetPrefsManager> cronet_prefs_manager_; 325 326 // The mapping between networks and their URLRequestContext. The only 327 // context guaranteed to exist for the entire lifetime of `this` is default 328 // one, which is associated to kInvalidNetworkHandle. 329 // For requests not requiring a specific network the default context must be 330 // used. 331 base::flat_map<net::handles::NetworkHandle, 332 std::unique_ptr<net::URLRequestContext>> 333 contexts_; 334 // Shorthand for the default context (needed by 335 // components/cronet/android/test/cronet_test_util.cc). 336 raw_ptr<net::URLRequestContext> default_context_; 337 338 bool is_default_context_initialized_; 339 340 // Context config is only valid until context is initialized. 341 std::unique_ptr<URLRequestContextConfig> context_config_; 342 343 // Effective experimental options. Kept for NetLog. 344 base::Value::Dict effective_experimental_options_; 345 346 // A queue of tasks that need to be run after context has been initialized. 347 base::queue<base::OnceClosure> tasks_waiting_for_context_; 348 349 // Task runner that runs network tasks. 350 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; 351 352 // Task runner that runs file tasks. 353 scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 354 355 // Callback implemented by the client. 356 std::unique_ptr<CronetContext::Callback> callback_; 357 358 THREAD_CHECKER(network_thread_checker_); 359 }; 360 361 private: 362 friend class TestUtil; 363 class ContextGetter; 364 365 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const; 366 367 // Gets the file thread. Create one if there is none. 368 base::Thread* GetFileThread(); 369 370 // Whether the connection status of active bidirectional streams should be 371 // monitored. 372 bool bidi_stream_detect_broken_connection_; 373 // If |bidi_stream_detect_broken_connection_| is true, this suggests the 374 // period of the heartbeat signal. 375 base::TimeDelta heartbeat_interval_; 376 377 const int default_load_flags_; 378 379 // File thread should be destroyed last. 380 std::unique_ptr<base::Thread> file_thread_; 381 382 // |network_tasks_| is owned by |this|. It is created off the network thread, 383 // but invoked and destroyed on network thread. 384 raw_ptr<NetworkTasks, AcrossTasksDanglingUntriaged> network_tasks_; 385 386 // Network thread is destroyed from client thread. 387 std::unique_ptr<base::Thread> network_thread_; 388 389 // Task runner that runs network tasks. 390 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; 391 }; 392 393 } // namespace cronet 394 395 #endif // COMPONENTS_CRONET_CRONET_CONTEXT_H_ 396