1 // Copyright 2014 The Chromium Authors. All rights reserved.
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_URL_REQUEST_CONTEXT_H_
6 #define COMPONENTS_CRONET_CRONET_URL_REQUEST_CONTEXT_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 
13 #include "base/callback.h"
14 #include "base/containers/queue.h"
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/threading/thread.h"
18 #include "base/threading/thread_checker.h"
19 #include "components/prefs/json_pref_store.h"
20 #include "net/nqe/effective_connection_type.h"
21 #include "net/nqe/effective_connection_type_observer.h"
22 #include "net/nqe/network_quality_estimator.h"
23 #include "net/nqe/network_quality_observation_source.h"
24 #include "net/nqe/rtt_throughput_estimates_observer.h"
25 
26 class PrefService;
27 
28 namespace base {
29 class SingleThreadTaskRunner;
30 class TimeTicks;
31 }  // namespace base
32 
33 namespace net {
34 enum EffectiveConnectionType;
35 class NetLog;
36 class ProxyConfigService;
37 class URLRequestContext;
38 class URLRequestContextGetter;
39 class FileNetLogObserver;
40 }  // namespace net
41 
42 namespace cronet {
43 class CronetPrefsManager;
44 class TestUtil;
45 
46 struct URLRequestContextConfig;
47 
48 // Wrapper around net::URLRequestContext.
49 class CronetURLRequestContext {
50  public:
51   // Callback implemented by CronetURLRequestContext() caller and owned by
52   // CronetURLRequestContext::NetworkTasks.
53   class Callback {
54    public:
55     virtual ~Callback() = default;
56 
57     // Invoked on network thread when initialized.
58     virtual void OnInitNetworkThread() = 0;
59 
60     // Invoked on network thread immediately prior to destruction.
61     virtual void OnDestroyNetworkThread() = 0;
62 
63     // net::NetworkQualityEstimator::EffectiveConnectionTypeObserver forwarder.
64     virtual void OnEffectiveConnectionTypeChanged(
65         net::EffectiveConnectionType effective_connection_type) = 0;
66 
67     // net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver
68     // forwarder.
69     virtual void OnRTTOrThroughputEstimatesComputed(
70         int32_t http_rtt_ms,
71         int32_t transport_rtt_ms,
72         int32_t downstream_throughput_kbps) = 0;
73 
74     // net::NetworkQualityEstimator::RTTObserver forwarder.
75     virtual void OnRTTObservation(
76         int32_t rtt_ms,
77         int32_t timestamp_ms,
78         net::NetworkQualityObservationSource source) = 0;
79 
80     // net::NetworkQualityEstimator::RTTObserver forwarder.
81     virtual void OnThroughputObservation(
82         int32_t throughput_kbps,
83         int32_t timestamp_ms,
84         net::NetworkQualityObservationSource source) = 0;
85 
86     // Callback for StopNetLog() that signals that it is safe to access
87     // the NetLog files.
88     virtual void OnStopNetLogCompleted() = 0;
89   };
90 
91   // Constructs CronetURLRequestContext using |context_config|. The |callback|
92   // is owned by |this| and is deleted on network thread.
93   // All |callback| methods are invoked on network thread.
94   // If the network_task_runner is not assigned, a network thread would be
95   // created for network tasks. Otherwise the tasks would be running on the
96   // assigned task runner.
97   CronetURLRequestContext(
98       std::unique_ptr<URLRequestContextConfig> context_config,
99       std::unique_ptr<Callback> callback,
100       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner =
101           nullptr);
102 
103   // Releases all resources for the request context and deletes the object.
104   // Blocks until network thread is destroyed after running all pending tasks.
105   virtual ~CronetURLRequestContext();
106 
107   // Called on init thread to initialize URLRequestContext.
108   void InitRequestContextOnInitThread();
109 
110   // Posts a task that might depend on the context being initialized
111   // to the network thread.
112   void PostTaskToNetworkThread(const base::Location& posted_from,
113                                base::OnceClosure callback);
114 
115   // Returns true if running on network thread.
116   bool IsOnNetworkThread() const;
117 
118   // Returns net::URLRequestContext owned by |this|.
119   net::URLRequestContext* GetURLRequestContext();
120 
121   // Returns a new instance of net::URLRequestContextGetter.
122   // The net::URLRequestContext and base::SingleThreadTaskRunner that
123   // net::URLRequestContextGetter returns are owned by |this|.
124   net::URLRequestContextGetter* CreateURLRequestContextGetter();
125 
126   // TODO(xunjieli): Keep only one version of StartNetLog().
127 
128   // Starts NetLog logging to file. This can be called on any thread.
129   // Return false if |file_name| cannot be opened.
130   bool StartNetLogToFile(const std::string& file_name, bool log_all);
131 
132   // Starts NetLog logging to disk with a bounded amount of disk space. This
133   // can be called on any thread.
134   void StartNetLogToDisk(const std::string& dir_name,
135                          bool log_all,
136                          int max_size);
137 
138   // Stops NetLog logging to file. This can be called on any thread. This will
139   // flush any remaining writes to disk.
140   void StopNetLog();
141 
142   // Default net::LOAD flags used to create requests.
143   int default_load_flags() const;
144 
145   // Configures the network quality estimator to observe requests to localhost,
146   // to use smaller responses when estimating throughput, and to disable the
147   // device offline checks when computing the effective connection type or when
148   // writing the prefs. This should only be used for testing. This can be
149   // called only after the network quality estimator has been enabled.
150   void ConfigureNetworkQualityEstimatorForTesting(bool use_local_host_requests,
151                                                   bool use_smaller_responses,
152                                                   bool disable_offline_check);
153 
154   // Request that RTT and/or throughput observations should or should not be
155   // provided by the network quality estimator.
156   void ProvideRTTObservations(bool should);
157   void ProvideThroughputObservations(bool should);
158 
159  private:
160   friend class TestUtil;
161   class ContextGetter;
162 
163   // NetworkTasks performs tasks on the network thread and owns objects that
164   // live on the network thread.
165   class NetworkTasks : public net::EffectiveConnectionTypeObserver,
166                        public net::RTTAndThroughputEstimatesObserver,
167                        public net::NetworkQualityEstimator::RTTObserver,
168                        public net::NetworkQualityEstimator::ThroughputObserver {
169    public:
170     // Invoked off the network thread.
171     NetworkTasks(std::unique_ptr<URLRequestContextConfig> config,
172                  std::unique_ptr<CronetURLRequestContext::Callback> callback);
173     // Invoked on the network thread.
174     ~NetworkTasks() override;
175 
176     // Initializes |context_| on the network thread.
177     void Initialize(
178         scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
179         scoped_refptr<base::SequencedTaskRunner> file_task_runner,
180         std::unique_ptr<net::ProxyConfigService> proxy_config_service);
181 
182     // Runs a task that might depend on the context being initialized.
183     void RunTaskAfterContextInit(
184         base::OnceClosure task_to_run_after_context_init);
185 
186     // Configures the network quality estimator to observe requests to
187     // localhost, to use smaller responses when estimating throughput, and to
188     // disable the device offline checks when computing the effective connection
189     // type or when writing the prefs. This should only be used for testing.
190     void ConfigureNetworkQualityEstimatorForTesting(
191         bool use_local_host_requests,
192         bool use_smaller_responses,
193         bool disable_offline_check);
194 
195     void ProvideRTTObservations(bool should);
196     void ProvideThroughputObservations(bool should);
197 
198     // net::NetworkQualityEstimator::EffectiveConnectionTypeObserver
199     // implementation.
200     void OnEffectiveConnectionTypeChanged(
201         net::EffectiveConnectionType effective_connection_type) override;
202 
203     // net::NetworkQualityEstimator::RTTAndThroughputEstimatesObserver
204     // implementation.
205     void OnRTTOrThroughputEstimatesComputed(
206         base::TimeDelta http_rtt,
207         base::TimeDelta transport_rtt,
208         int32_t downstream_throughput_kbps) override;
209 
210     // net::NetworkQualityEstimator::RTTObserver implementation.
211     void OnRTTObservation(int32_t rtt_ms,
212                           const base::TimeTicks& timestamp,
213                           net::NetworkQualityObservationSource source) override;
214 
215     // net::NetworkQualityEstimator::ThroughputObserver implementation.
216     void OnThroughputObservation(
217         int32_t throughput_kbps,
218         const base::TimeTicks& timestamp,
219         net::NetworkQualityObservationSource source) override;
220 
221     net::URLRequestContext* GetURLRequestContext();
222 
223     // Same as StartNetLogToDisk.
224     void StartNetLogToBoundedFile(const std::string& dir_path,
225                                   bool include_socket_bytes,
226                                   int size);
227 
228     // Same as StartNetLogToFile, but called only on the network thread.
229     void StartNetLog(const base::FilePath& file_path,
230                      bool include_socket_bytes);
231 
232     // Stops NetLog logging.
233     void StopNetLog();
234 
235     // Callback for StopObserving() that unblocks the client thread and
236     // signals that it is safe to access the NetLog files.
237     void StopNetLogCompleted();
238 
239     // Initializes Network Quality Estimator (NQE) prefs manager on network
240     // thread.
241     void InitializeNQEPrefs() const;
242 
243    private:
244     friend class TestUtil;
245     base::Value GetNetLogInfo() const;
246 
247     std::unique_ptr<net::FileNetLogObserver> net_log_file_observer_;
248 
249     // A network quality estimator. This member variable has to be destroyed
250     // after destroying |cronet_prefs_manager_|, which owns
251     // NetworkQualityPrefsManager that weakly references
252     // |network_quality_estimator_|.
253     std::unique_ptr<net::NetworkQualityEstimator> network_quality_estimator_;
254 
255     // Manages the PrefService and all associated persistence managers
256     // such as NetworkQualityPrefsManager, HostCachePersistenceManager, etc.
257     // It should be destroyed before |network_quality_estimator_| and
258     // after |context_|.
259     std::unique_ptr<CronetPrefsManager> cronet_prefs_manager_;
260 
261     std::unique_ptr<net::URLRequestContext> context_;
262     bool is_context_initialized_;
263 
264     // Context config is only valid until context is initialized.
265     std::unique_ptr<URLRequestContextConfig> context_config_;
266 
267     // Effective experimental options. Kept for NetLog.
268     std::unique_ptr<base::DictionaryValue> effective_experimental_options_;
269 
270     // A queue of tasks that need to be run after context has been initialized.
271     base::queue<base::OnceClosure> tasks_waiting_for_context_;
272 
273     // Task runner that runs network tasks.
274     scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
275 
276     // Callback implemented by the client.
277     std::unique_ptr<CronetURLRequestContext::Callback> callback_;
278 
279     THREAD_CHECKER(network_thread_checker_);
280     DISALLOW_COPY_AND_ASSIGN(NetworkTasks);
281   };
282 
283   scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const;
284 
285   // Gets the file thread. Create one if there is none.
286   base::Thread* GetFileThread();
287 
288   const int default_load_flags_;
289 
290   // File thread should be destroyed last.
291   std::unique_ptr<base::Thread> file_thread_;
292 
293   // |network_tasks_| is owned by |this|. It is created off the network thread,
294   // but invoked and destroyed on network thread.
295   NetworkTasks* network_tasks_;
296 
297   // Network thread is destroyed from client thread.
298   std::unique_ptr<base::Thread> network_thread_;
299 
300   // Task runner that runs network tasks.
301   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
302 
303   DISALLOW_COPY_AND_ASSIGN(CronetURLRequestContext);
304 };
305 
306 }  // namespace cronet
307 
308 #endif  // COMPONENTS_CRONET_CRONET_URL_REQUEST_CONTEXT_H_
309