Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/cronet/android/cronet_url_request_adapter.h" | 5 #include "components/cronet/android/cronet_url_request_adapter.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 const GURL& url, | 85 const GURL& url, |
| 86 net::RequestPriority priority, | 86 net::RequestPriority priority, |
| 87 jboolean jdisable_cache, | 87 jboolean jdisable_cache, |
| 88 jboolean jdisable_connection_migration, | 88 jboolean jdisable_connection_migration, |
| 89 jboolean jenable_metrics) | 89 jboolean jenable_metrics) |
| 90 : context_(context), | 90 : context_(context), |
| 91 initial_url_(url), | 91 initial_url_(url), |
| 92 initial_priority_(priority), | 92 initial_priority_(priority), |
| 93 initial_method_("GET"), | 93 initial_method_("GET"), |
| 94 load_flags_(context->default_load_flags()), | 94 load_flags_(context->default_load_flags()), |
| 95 enable_metrics_(jenable_metrics == JNI_TRUE) { | 95 enable_metrics_(jenable_metrics == JNI_TRUE), |
| 96 weak_ptr_factory_(this) { | |
| 96 DCHECK(!context_->IsOnNetworkThread()); | 97 DCHECK(!context_->IsOnNetworkThread()); |
| 97 owner_.Reset(env, jurl_request); | 98 owner_.Reset(env, jurl_request); |
| 98 if (jdisable_cache == JNI_TRUE) | 99 if (jdisable_cache == JNI_TRUE) |
| 99 load_flags_ |= net::LOAD_DISABLE_CACHE; | 100 load_flags_ |= net::LOAD_DISABLE_CACHE; |
| 100 if (jdisable_connection_migration == JNI_TRUE) | 101 if (jdisable_connection_migration == JNI_TRUE) |
| 101 load_flags_ |= net::LOAD_DISABLE_CONNECTION_MIGRATION; | 102 load_flags_ |= net::LOAD_DISABLE_CONNECTION_MIGRATION; |
| 102 } | 103 } |
| 103 | 104 |
| 104 CronetURLRequestAdapter::~CronetURLRequestAdapter() { | 105 CronetURLRequestAdapter::~CronetURLRequestAdapter() { |
| 105 DCHECK(context_->IsOnNetworkThread()); | 106 DCHECK(context_->IsOnNetworkThread()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 DCHECK(!context_->IsOnNetworkThread()); | 140 DCHECK(!context_->IsOnNetworkThread()); |
| 140 DCHECK(!upload_); | 141 DCHECK(!upload_); |
| 141 upload_ = std::move(upload); | 142 upload_ = std::move(upload); |
| 142 } | 143 } |
| 143 | 144 |
| 144 void CronetURLRequestAdapter::Start(JNIEnv* env, | 145 void CronetURLRequestAdapter::Start(JNIEnv* env, |
| 145 const JavaParamRef<jobject>& jcaller) { | 146 const JavaParamRef<jobject>& jcaller) { |
| 146 DCHECK(!context_->IsOnNetworkThread()); | 147 DCHECK(!context_->IsOnNetworkThread()); |
| 147 context_->PostTaskToNetworkThread( | 148 context_->PostTaskToNetworkThread( |
| 148 FROM_HERE, base::Bind(&CronetURLRequestAdapter::StartOnNetworkThread, | 149 FROM_HERE, base::Bind(&CronetURLRequestAdapter::StartOnNetworkThread, |
| 149 base::Unretained(this))); | 150 weak_ptr_factory_.GetWeakPtr())); |
| 150 } | 151 } |
| 151 | 152 |
| 152 void CronetURLRequestAdapter::GetStatus( | 153 void CronetURLRequestAdapter::GetStatus( |
| 153 JNIEnv* env, | 154 JNIEnv* env, |
| 154 const JavaParamRef<jobject>& jcaller, | 155 const JavaParamRef<jobject>& jcaller, |
| 155 const JavaParamRef<jobject>& jstatus_listener) const { | 156 const JavaParamRef<jobject>& jstatus_listener) { |
| 156 base::android::ScopedJavaGlobalRef<jobject> status_listener_ref; | 157 base::android::ScopedJavaGlobalRef<jobject> status_listener_ref; |
| 157 status_listener_ref.Reset(env, jstatus_listener); | 158 status_listener_ref.Reset(env, jstatus_listener); |
| 158 context_->PostTaskToNetworkThread( | 159 context_->PostTaskToNetworkThread( |
| 159 FROM_HERE, base::Bind(&CronetURLRequestAdapter::GetStatusOnNetworkThread, | 160 FROM_HERE, |
| 160 base::Unretained(this), status_listener_ref)); | 161 base::Bind(&CronetURLRequestAdapter::GetStatusOnNetworkThread, |
| 162 weak_ptr_factory_.GetWeakPtr(), status_listener_ref)); | |
| 161 } | 163 } |
| 162 | 164 |
| 163 void CronetURLRequestAdapter::FollowDeferredRedirect( | 165 void CronetURLRequestAdapter::FollowDeferredRedirect( |
| 164 JNIEnv* env, | 166 JNIEnv* env, |
| 165 const JavaParamRef<jobject>& jcaller) { | 167 const JavaParamRef<jobject>& jcaller) { |
| 166 context_->PostTaskToNetworkThread( | 168 context_->PostTaskToNetworkThread( |
| 167 FROM_HERE, | 169 FROM_HERE, |
| 168 base::Bind( | 170 base::Bind( |
| 169 &CronetURLRequestAdapter::FollowDeferredRedirectOnNetworkThread, | 171 &CronetURLRequestAdapter::FollowDeferredRedirectOnNetworkThread, |
| 170 base::Unretained(this))); | 172 weak_ptr_factory_.GetWeakPtr())); |
| 171 } | 173 } |
| 172 | 174 |
| 173 jboolean CronetURLRequestAdapter::ReadData( | 175 jboolean CronetURLRequestAdapter::ReadData( |
| 174 JNIEnv* env, | 176 JNIEnv* env, |
| 175 const JavaParamRef<jobject>& jcaller, | 177 const JavaParamRef<jobject>& jcaller, |
| 176 const JavaParamRef<jobject>& jbyte_buffer, | 178 const JavaParamRef<jobject>& jbyte_buffer, |
| 177 jint jposition, | 179 jint jposition, |
| 178 jint jlimit) { | 180 jint jlimit) { |
| 179 DCHECK_LT(jposition, jlimit); | 181 DCHECK_LT(jposition, jlimit); |
| 180 | 182 |
| 181 void* data = env->GetDirectBufferAddress(jbyte_buffer); | 183 void* data = env->GetDirectBufferAddress(jbyte_buffer); |
| 182 if (!data) | 184 if (!data) |
| 183 return JNI_FALSE; | 185 return JNI_FALSE; |
| 184 | 186 |
| 185 scoped_refptr<IOBufferWithByteBuffer> read_buffer( | 187 scoped_refptr<IOBufferWithByteBuffer> read_buffer( |
| 186 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); | 188 new IOBufferWithByteBuffer(env, jbyte_buffer, data, jposition, jlimit)); |
| 187 | 189 |
| 188 int remaining_capacity = jlimit - jposition; | 190 int remaining_capacity = jlimit - jposition; |
| 189 | 191 |
| 190 context_->PostTaskToNetworkThread( | 192 context_->PostTaskToNetworkThread( |
| 191 FROM_HERE, base::Bind(&CronetURLRequestAdapter::ReadDataOnNetworkThread, | 193 FROM_HERE, base::Bind(&CronetURLRequestAdapter::ReadDataOnNetworkThread, |
| 192 base::Unretained(this), | 194 weak_ptr_factory_.GetWeakPtr(), read_buffer, |
| 193 read_buffer, | |
| 194 remaining_capacity)); | 195 remaining_capacity)); |
| 195 return JNI_TRUE; | 196 return JNI_TRUE; |
| 196 } | 197 } |
| 197 | 198 |
| 198 void CronetURLRequestAdapter::Destroy(JNIEnv* env, | 199 void CronetURLRequestAdapter::Destroy(JNIEnv* env, |
| 199 const JavaParamRef<jobject>& jcaller, | 200 const JavaParamRef<jobject>& jcaller) { |
| 200 jboolean jsend_on_canceled) { | |
| 201 // Destroy could be called from any thread, including network thread (if | |
| 202 // posting task to executor throws an exception), but is posted, so |this| | |
| 203 // is valid until calling task is complete. Destroy() is always called from | |
| 204 // within a synchronized java block that guarantees no future posts to the | |
| 205 // network thread with the adapter pointer. | |
| 206 context_->PostTaskToNetworkThread( | 201 context_->PostTaskToNetworkThread( |
| 207 FROM_HERE, base::Bind(&CronetURLRequestAdapter::DestroyOnNetworkThread, | 202 FROM_HERE, base::Bind(&CronetURLRequestAdapter::DestroyOnNetworkThread, |
| 208 base::Unretained(this), jsend_on_canceled)); | 203 weak_ptr_factory_.GetWeakPtr())); |
| 204 } | |
| 205 | |
| 206 void CronetURLRequestAdapter::Cancel(JNIEnv* env, | |
| 207 const JavaParamRef<jobject>& jcaller) { | |
| 208 context_->PostTaskToNetworkThread( | |
| 209 FROM_HERE, base::Bind(&CronetURLRequestAdapter::CancelOnNetworkThread, | |
|
mef
2017/04/27 21:33:13
Hrm, from comment on WeakPtrFactory:
// Note that
xunjieli
2017/04/28 13:36:47
Ah, thanks, You are right! I missed this. I tried
| |
| 210 weak_ptr_factory_.GetWeakPtr())); | |
| 209 } | 211 } |
| 210 | 212 |
| 211 void CronetURLRequestAdapter::OnReceivedRedirect( | 213 void CronetURLRequestAdapter::OnReceivedRedirect( |
| 212 net::URLRequest* request, | 214 net::URLRequest* request, |
| 213 const net::RedirectInfo& redirect_info, | 215 const net::RedirectInfo& redirect_info, |
| 214 bool* defer_redirect) { | 216 bool* defer_redirect) { |
| 215 DCHECK(context_->IsOnNetworkThread()); | 217 DCHECK(context_->IsOnNetworkThread()); |
| 216 JNIEnv* env = base::android::AttachCurrentThread(); | 218 JNIEnv* env = base::android::AttachCurrentThread(); |
| 217 cronet::Java_CronetUrlRequest_onRedirectReceived( | 219 cronet::Java_CronetUrlRequest_onRedirectReceived( |
| 218 env, owner_.obj(), | 220 env, owner_.obj(), |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 238 request->ContinueWithCertificate(nullptr, nullptr); | 240 request->ContinueWithCertificate(nullptr, nullptr); |
| 239 } | 241 } |
| 240 | 242 |
| 241 void CronetURLRequestAdapter::OnSSLCertificateError( | 243 void CronetURLRequestAdapter::OnSSLCertificateError( |
| 242 net::URLRequest* request, | 244 net::URLRequest* request, |
| 243 const net::SSLInfo& ssl_info, | 245 const net::SSLInfo& ssl_info, |
| 244 bool fatal) { | 246 bool fatal) { |
| 245 DCHECK(context_->IsOnNetworkThread()); | 247 DCHECK(context_->IsOnNetworkThread()); |
| 246 request->Cancel(); | 248 request->Cancel(); |
| 247 int net_error = net::MapCertStatusToNetError(ssl_info.cert_status); | 249 int net_error = net::MapCertStatusToNetError(ssl_info.cert_status); |
| 248 JNIEnv* env = base::android::AttachCurrentThread(); | 250 ReportError(request, net_error); |
|
mef
2017/04/27 21:33:13
nice!
| |
| 249 cronet::Java_CronetUrlRequest_onError( | |
| 250 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error, | |
| 251 net::QUIC_NO_ERROR, | |
| 252 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(), | |
| 253 request->GetTotalReceivedBytes()); | |
| 254 } | 251 } |
| 255 | 252 |
| 256 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest* request, | 253 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest* request, |
| 257 int net_error) { | 254 int net_error) { |
| 258 DCHECK_NE(net::ERR_IO_PENDING, net_error); | 255 DCHECK_NE(net::ERR_IO_PENDING, net_error); |
| 259 DCHECK(context_->IsOnNetworkThread()); | 256 DCHECK(context_->IsOnNetworkThread()); |
| 260 | 257 |
| 261 if (net_error != net::OK) { | 258 if (net_error != net::OK) { |
| 262 ReportError(request, net_error); | 259 ReportError(request, net_error); |
| 263 return; | 260 return; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 279 int bytes_read) { | 276 int bytes_read) { |
| 280 DCHECK(context_->IsOnNetworkThread()); | 277 DCHECK(context_->IsOnNetworkThread()); |
| 281 | 278 |
| 282 if (bytes_read < 0) { | 279 if (bytes_read < 0) { |
| 283 ReportError(request, bytes_read); | 280 ReportError(request, bytes_read); |
| 284 return; | 281 return; |
| 285 } | 282 } |
| 286 | 283 |
| 287 if (bytes_read == 0) { | 284 if (bytes_read == 0) { |
| 288 JNIEnv* env = base::android::AttachCurrentThread(); | 285 JNIEnv* env = base::android::AttachCurrentThread(); |
| 289 cronet::Java_CronetUrlRequest_onSucceeded( | 286 cronet::Java_CronetUrlRequest_onSucceeded(env, owner_.obj(), |
| 290 env, owner_.obj(), url_request_->GetTotalReceivedBytes()); | 287 request->GetTotalReceivedBytes()); |
| 288 DestroyOnNetworkThread(); | |
| 291 } else { | 289 } else { |
| 292 JNIEnv* env = base::android::AttachCurrentThread(); | 290 JNIEnv* env = base::android::AttachCurrentThread(); |
| 293 cronet::Java_CronetUrlRequest_onReadCompleted( | 291 cronet::Java_CronetUrlRequest_onReadCompleted( |
| 294 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read, | 292 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read, |
| 295 read_buffer_->initial_position(), read_buffer_->initial_limit(), | 293 read_buffer_->initial_position(), read_buffer_->initial_limit(), |
| 296 request->GetTotalReceivedBytes()); | 294 request->GetTotalReceivedBytes()); |
| 297 // Free the read buffer. This lets the Java ByteBuffer be freed, if the | 295 // Free the read buffer. This lets the Java ByteBuffer be freed, if the |
| 298 // embedder releases it, too. | 296 // embedder releases it, too. |
| 299 read_buffer_ = nullptr; | 297 read_buffer_ = nullptr; |
| 300 } | 298 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 read_buffer_ = read_buffer; | 364 read_buffer_ = read_buffer; |
| 367 | 365 |
| 368 int result = url_request_->Read(read_buffer_.get(), buffer_size); | 366 int result = url_request_->Read(read_buffer_.get(), buffer_size); |
| 369 // If IO is pending, wait for the URLRequest to call OnReadCompleted. | 367 // If IO is pending, wait for the URLRequest to call OnReadCompleted. |
| 370 if (result == net::ERR_IO_PENDING) | 368 if (result == net::ERR_IO_PENDING) |
| 371 return; | 369 return; |
| 372 | 370 |
| 373 OnReadCompleted(url_request_.get(), result); | 371 OnReadCompleted(url_request_.get(), result); |
| 374 } | 372 } |
| 375 | 373 |
| 376 void CronetURLRequestAdapter::DestroyOnNetworkThread(bool send_on_canceled) { | 374 void CronetURLRequestAdapter::DestroyOnNetworkThread() { |
| 377 DCHECK(context_->IsOnNetworkThread()); | 375 DCHECK(context_->IsOnNetworkThread()); |
| 378 JNIEnv* env = base::android::AttachCurrentThread(); | 376 JNIEnv* env = base::android::AttachCurrentThread(); |
| 379 if (send_on_canceled) { | 377 cronet::Java_CronetUrlRequest_onDestroyed(env, owner_.obj()); |
| 380 cronet::Java_CronetUrlRequest_onCanceled(env, owner_.obj()); | |
| 381 } | |
| 382 MaybeReportMetrics(env); | 378 MaybeReportMetrics(env); |
| 383 delete this; | 379 delete this; |
| 384 } | 380 } |
| 385 | 381 |
| 382 void CronetURLRequestAdapter::CancelOnNetworkThread() { | |
| 383 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 384 cronet::Java_CronetUrlRequest_onCanceled(env, owner_.obj()); | |
| 385 DestroyOnNetworkThread(); | |
| 386 } | |
| 387 | |
| 386 void CronetURLRequestAdapter::ReportError(net::URLRequest* request, | 388 void CronetURLRequestAdapter::ReportError(net::URLRequest* request, |
| 387 int net_error) { | 389 int net_error) { |
| 388 DCHECK_NE(net::ERR_IO_PENDING, net_error); | 390 DCHECK_NE(net::ERR_IO_PENDING, net_error); |
| 389 DCHECK_LT(net_error, 0); | 391 DCHECK_LT(net_error, 0); |
| 390 DCHECK_EQ(request, url_request_.get()); | 392 DCHECK_EQ(request, url_request_.get()); |
| 391 | 393 |
| 392 net::NetErrorDetails net_error_details; | 394 net::NetErrorDetails net_error_details; |
| 393 url_request_->PopulateNetErrorDetails(&net_error_details); | 395 url_request_->PopulateNetErrorDetails(&net_error_details); |
| 394 VLOG(1) << "Error " << net::ErrorToString(net_error) | 396 VLOG(1) << "Error " << net::ErrorToString(net_error) |
| 395 << " on chromium request: " << initial_url_.possibly_invalid_spec(); | 397 << " on chromium request: " << initial_url_.possibly_invalid_spec(); |
| 396 JNIEnv* env = base::android::AttachCurrentThread(); | 398 JNIEnv* env = base::android::AttachCurrentThread(); |
| 397 cronet::Java_CronetUrlRequest_onError( | 399 cronet::Java_CronetUrlRequest_onError( |
| 398 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error, | 400 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error, |
| 399 net_error_details.quic_connection_error, | 401 net_error_details.quic_connection_error, |
| 400 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(), | 402 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(), |
| 401 request->GetTotalReceivedBytes()); | 403 request->GetTotalReceivedBytes()); |
| 404 DestroyOnNetworkThread(); | |
| 402 } | 405 } |
| 403 | 406 |
| 404 void CronetURLRequestAdapter::MaybeReportMetrics(JNIEnv* env) const { | 407 void CronetURLRequestAdapter::MaybeReportMetrics(JNIEnv* env) const { |
| 405 // If there was an exception while starting the CronetUrlRequest, there won't | 408 // If there was an exception while starting the CronetUrlRequest, there won't |
| 406 // be a native URLRequest. In this case, the caller gets the exception | 409 // be a native URLRequest. In this case, the caller gets the exception |
| 407 // immediately, and the onFailed callback isn't called, so don't report | 410 // immediately, and the onFailed callback isn't called, so don't report |
| 408 // metrics either. | 411 // metrics either. |
| 409 if (!enable_metrics_ || !url_request_) { | 412 if (!enable_metrics_ || !url_request_) { |
| 410 return; | 413 return; |
| 411 } | 414 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 434 metrics_util::ConvertTime(metrics.push_end, start_ticks, start_time), | 437 metrics_util::ConvertTime(metrics.push_end, start_ticks, start_time), |
| 435 metrics_util::ConvertTime(metrics.receive_headers_end, start_ticks, | 438 metrics_util::ConvertTime(metrics.receive_headers_end, start_ticks, |
| 436 start_time), | 439 start_time), |
| 437 metrics_util::ConvertTime(base::TimeTicks::Now(), start_ticks, | 440 metrics_util::ConvertTime(base::TimeTicks::Now(), start_ticks, |
| 438 start_time), | 441 start_time), |
| 439 metrics.socket_reused, url_request_->GetTotalSentBytes(), | 442 metrics.socket_reused, url_request_->GetTotalSentBytes(), |
| 440 url_request_->GetTotalReceivedBytes()); | 443 url_request_->GetTotalReceivedBytes()); |
| 441 } | 444 } |
| 442 | 445 |
| 443 } // namespace cronet | 446 } // namespace cronet |
| OLD | NEW |