xref: /aosp_15_r20/external/cronet/components/cronet/cronet_context.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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