Revert of Refactor the avatar button/icon class (patchset #14 id:320001 of https...
[chromium-blink-merge.git] / components / cronet / android / cronet_url_request_context_adapter.cc
blobec52c9a4c1721a4219f836f1ef40024629276dd0
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.
5 #include "components/cronet/android/cronet_url_request_context_adapter.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/bind.h"
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_file.h"
12 #include "base/logging.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/values.h"
15 #include "components/cronet/url_request_context_config.h"
16 #include "jni/CronetUrlRequestContext_jni.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/network_delegate_impl.h"
20 #include "net/http/http_auth_handler_factory.h"
21 #include "net/log/write_to_file_net_log_observer.h"
22 #include "net/proxy/proxy_service.h"
23 #include "net/sdch/sdch_owner.h"
24 #include "net/url_request/url_request_context.h"
25 #include "net/url_request/url_request_context_builder.h"
27 namespace {
29 class BasicNetworkDelegate : public net::NetworkDelegateImpl {
30 public:
31 BasicNetworkDelegate() {}
32 ~BasicNetworkDelegate() override {}
34 private:
35 // net::NetworkDelegate implementation.
36 int OnBeforeURLRequest(net::URLRequest* request,
37 const net::CompletionCallback& callback,
38 GURL* new_url) override {
39 return net::OK;
42 int OnBeforeSendHeaders(net::URLRequest* request,
43 const net::CompletionCallback& callback,
44 net::HttpRequestHeaders* headers) override {
45 return net::OK;
48 void OnSendHeaders(net::URLRequest* request,
49 const net::HttpRequestHeaders& headers) override {}
51 int OnHeadersReceived(
52 net::URLRequest* request,
53 const net::CompletionCallback& callback,
54 const net::HttpResponseHeaders* original_response_headers,
55 scoped_refptr<net::HttpResponseHeaders>* _response_headers,
56 GURL* allowed_unsafe_redirect_url) override {
57 return net::OK;
60 void OnBeforeRedirect(net::URLRequest* request,
61 const GURL& new_location) override {}
63 void OnResponseStarted(net::URLRequest* request) override {}
65 void OnRawBytesRead(const net::URLRequest& request, int bytes_read) override {
68 void OnCompleted(net::URLRequest* request, bool started) override {}
70 void OnURLRequestDestroyed(net::URLRequest* request) override {}
72 void OnPACScriptError(int line_number, const base::string16& error) override {
75 NetworkDelegate::AuthRequiredResponse OnAuthRequired(
76 net::URLRequest* request,
77 const net::AuthChallengeInfo& auth_info,
78 const AuthCallback& callback,
79 net::AuthCredentials* credentials) override {
80 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
83 bool OnCanGetCookies(const net::URLRequest& request,
84 const net::CookieList& cookie_list) override {
85 return false;
88 bool OnCanSetCookie(const net::URLRequest& request,
89 const std::string& cookie_line,
90 net::CookieOptions* options) override {
91 return false;
94 bool OnCanAccessFile(const net::URLRequest& request,
95 const base::FilePath& path) const override {
96 return false;
99 bool OnCanThrottleRequest(const net::URLRequest& request) const override {
100 return false;
103 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
106 } // namespace
108 namespace cronet {
110 // Explicitly register static JNI functions.
111 bool CronetUrlRequestContextAdapterRegisterJni(JNIEnv* env) {
112 return RegisterNativesImpl(env);
115 CronetURLRequestContextAdapter::CronetURLRequestContextAdapter(
116 scoped_ptr<URLRequestContextConfig> context_config)
117 : network_thread_(new base::Thread("network")),
118 context_config_(context_config.Pass()),
119 is_context_initialized_(false),
120 default_load_flags_(net::LOAD_NORMAL) {
121 base::Thread::Options options;
122 options.message_loop_type = base::MessageLoop::TYPE_IO;
123 network_thread_->StartWithOptions(options);
126 CronetURLRequestContextAdapter::~CronetURLRequestContextAdapter() {
127 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
128 StopNetLogOnNetworkThread();
131 void CronetURLRequestContextAdapter::InitRequestContextOnMainThread(
132 JNIEnv* env,
133 jobject jcaller) {
134 base::android::ScopedJavaGlobalRef<jobject> jcaller_ref;
135 jcaller_ref.Reset(env, jcaller);
136 proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(
137 GetNetworkTaskRunner(), nullptr));
138 GetNetworkTaskRunner()->PostTask(
139 FROM_HERE,
140 base::Bind(&CronetURLRequestContextAdapter::InitializeOnNetworkThread,
141 base::Unretained(this), Passed(&context_config_),
142 jcaller_ref));
145 void CronetURLRequestContextAdapter::InitializeOnNetworkThread(
146 scoped_ptr<URLRequestContextConfig> config,
147 const base::android::ScopedJavaGlobalRef<jobject>&
148 jcronet_url_request_context) {
149 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
150 DCHECK(!is_context_initialized_);
151 DCHECK(proxy_config_service_);
152 // TODO(mmenke): Add method to have the builder enable SPDY.
153 net::URLRequestContextBuilder context_builder;
154 context_builder.set_network_delegate(new BasicNetworkDelegate());
155 context_builder.set_proxy_config_service(proxy_config_service_.release());
156 config->ConfigureURLRequestContextBuilder(&context_builder);
158 context_.reset(context_builder.Build());
160 default_load_flags_ = net::LOAD_DO_NOT_SAVE_COOKIES |
161 net::LOAD_DO_NOT_SEND_COOKIES;
162 if (config->load_disable_cache)
163 default_load_flags_ |= net::LOAD_DISABLE_CACHE;
165 if (config->enable_sdch) {
166 DCHECK(context_->sdch_manager());
167 sdch_owner_.reset(
168 new net::SdchOwner(context_->sdch_manager(), context_.get()));
171 // Currently (circa M39) enabling QUIC requires setting probability threshold.
172 if (config->enable_quic) {
173 context_->http_server_properties()
174 ->SetAlternativeServiceProbabilityThreshold(0.0f);
175 for (auto hint = config->quic_hints.begin();
176 hint != config->quic_hints.end(); ++hint) {
177 const URLRequestContextConfig::QuicHint& quic_hint = **hint;
178 if (quic_hint.host.empty()) {
179 LOG(ERROR) << "Empty QUIC hint host: " << quic_hint.host;
180 continue;
183 url::CanonHostInfo host_info;
184 std::string canon_host(net::CanonicalizeHost(quic_hint.host, &host_info));
185 if (!host_info.IsIPAddress() &&
186 !net::IsCanonicalizedHostCompliant(canon_host)) {
187 LOG(ERROR) << "Invalid QUIC hint host: " << quic_hint.host;
188 continue;
191 if (quic_hint.port <= std::numeric_limits<uint16>::min() ||
192 quic_hint.port > std::numeric_limits<uint16>::max()) {
193 LOG(ERROR) << "Invalid QUIC hint port: "
194 << quic_hint.port;
195 continue;
198 if (quic_hint.alternate_port <= std::numeric_limits<uint16>::min() ||
199 quic_hint.alternate_port > std::numeric_limits<uint16>::max()) {
200 LOG(ERROR) << "Invalid QUIC hint alternate port: "
201 << quic_hint.alternate_port;
202 continue;
205 net::HostPortPair quic_hint_host_port_pair(canon_host,
206 quic_hint.port);
207 net::AlternativeService alternative_service(
208 net::AlternateProtocol::QUIC, "",
209 static_cast<uint16>(quic_hint.alternate_port));
210 context_->http_server_properties()->SetAlternativeService(
211 quic_hint_host_port_pair, alternative_service, 1.0f);
215 JNIEnv* env = base::android::AttachCurrentThread();
216 Java_CronetUrlRequestContext_initNetworkThread(
217 env, jcronet_url_request_context.obj());
219 is_context_initialized_ = true;
220 while (!tasks_waiting_for_context_.empty()) {
221 tasks_waiting_for_context_.front().Run();
222 tasks_waiting_for_context_.pop();
226 void CronetURLRequestContextAdapter::Destroy(JNIEnv* env, jobject jcaller) {
227 DCHECK(!GetNetworkTaskRunner()->BelongsToCurrentThread());
228 // Stick network_thread_ in a local, as |this| may be destroyed from the
229 // network thread before delete network_thread is called.
230 base::Thread* network_thread = network_thread_;
231 GetNetworkTaskRunner()->DeleteSoon(FROM_HERE, this);
232 // Deleting thread stops it after all tasks are completed.
233 delete network_thread;
236 net::URLRequestContext* CronetURLRequestContextAdapter::GetURLRequestContext() {
237 if (!context_) {
238 LOG(ERROR) << "URLRequestContext is not set up";
240 return context_.get();
243 void CronetURLRequestContextAdapter::PostTaskToNetworkThread(
244 const tracked_objects::Location& posted_from,
245 const base::Closure& callback) {
246 GetNetworkTaskRunner()->PostTask(
247 posted_from, base::Bind(&CronetURLRequestContextAdapter::
248 RunTaskAfterContextInitOnNetworkThread,
249 base::Unretained(this), callback));
252 void CronetURLRequestContextAdapter::RunTaskAfterContextInitOnNetworkThread(
253 const base::Closure& task_to_run_after_context_init) {
254 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
255 if (is_context_initialized_) {
256 DCHECK(tasks_waiting_for_context_.empty());
257 task_to_run_after_context_init.Run();
258 return;
260 tasks_waiting_for_context_.push(task_to_run_after_context_init);
263 bool CronetURLRequestContextAdapter::IsOnNetworkThread() const {
264 return GetNetworkTaskRunner()->BelongsToCurrentThread();
267 scoped_refptr<base::SingleThreadTaskRunner>
268 CronetURLRequestContextAdapter::GetNetworkTaskRunner() const {
269 return network_thread_->task_runner();
272 void CronetURLRequestContextAdapter::StartNetLogToFile(JNIEnv* env,
273 jobject jcaller,
274 jstring jfile_name,
275 jboolean jlog_all) {
276 PostTaskToNetworkThread(
277 FROM_HERE,
278 base::Bind(
279 &CronetURLRequestContextAdapter::StartNetLogToFileOnNetworkThread,
280 base::Unretained(this),
281 base::android::ConvertJavaStringToUTF8(env, jfile_name), jlog_all));
284 void CronetURLRequestContextAdapter::StopNetLog(JNIEnv* env, jobject jcaller) {
285 PostTaskToNetworkThread(
286 FROM_HERE,
287 base::Bind(&CronetURLRequestContextAdapter::StopNetLogOnNetworkThread,
288 base::Unretained(this)));
291 void CronetURLRequestContextAdapter::StartNetLogToFileOnNetworkThread(
292 const std::string& file_name, bool log_all) {
293 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
294 DCHECK(is_context_initialized_);
295 DCHECK(context_);
296 // Do nothing if already logging to a file.
297 if (write_to_file_observer_)
298 return;
299 base::FilePath file_path(file_name);
300 base::ScopedFILE file(base::OpenFile(file_path, "w"));
301 if (!file)
302 return;
304 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
305 if (log_all) {
306 write_to_file_observer_->set_capture_mode(
307 net::NetLogCaptureMode::IncludeSocketBytes());
309 write_to_file_observer_->StartObserving(context_->net_log(), file.Pass(),
310 nullptr, context_.get());
313 void CronetURLRequestContextAdapter::StopNetLogOnNetworkThread() {
314 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
315 if (write_to_file_observer_) {
316 write_to_file_observer_->StopObserving(context_.get());
317 write_to_file_observer_.reset();
321 // Creates RequestContextAdater if config is valid URLRequestContextConfig,
322 // returns 0 otherwise.
323 static jlong CreateRequestContextAdapter(JNIEnv* env,
324 jclass jcaller,
325 jstring jconfig) {
326 std::string config_string =
327 base::android::ConvertJavaStringToUTF8(env, jconfig);
328 scoped_ptr<URLRequestContextConfig> context_config(
329 new URLRequestContextConfig());
330 if (!context_config->LoadFromJSON(config_string))
331 return 0;
333 CronetURLRequestContextAdapter* context_adapter =
334 new CronetURLRequestContextAdapter(context_config.Pass());
335 return reinterpret_cast<jlong>(context_adapter);
338 static jint SetMinLogLevel(JNIEnv* env, jclass jcaller, jint jlog_level) {
339 jint old_log_level = static_cast<jint>(logging::GetMinLogLevel());
340 // MinLogLevel is global, shared by all URLRequestContexts.
341 logging::SetMinLogLevel(static_cast<int>(jlog_level));
342 return old_log_level;
345 } // namespace cronet