Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: components/cronet/android/cronet_url_request_adapter.cc

Issue 2351793003: Implement timing metrics for UrlRequest (Closed)
Patch Set: New test, and some rearranging things Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 15 matching lines...) Expand all
26 #include "net/quic/core/quic_protocol.h" 26 #include "net/quic/core/quic_protocol.h"
27 #include "net/ssl/ssl_info.h" 27 #include "net/ssl/ssl_info.h"
28 #include "net/url_request/redirect_info.h" 28 #include "net/url_request/redirect_info.h"
29 #include "net/url_request/url_request_context.h" 29 #include "net/url_request/url_request_context.h"
30 30
31 using base::android::ConvertUTF8ToJavaString; 31 using base::android::ConvertUTF8ToJavaString;
32 using base::android::JavaParamRef; 32 using base::android::JavaParamRef;
33 33
34 namespace cronet { 34 namespace cronet {
35 35
36 namespace {
37
38 // Converts timing metrics stored as TimeTicks into the format expected by the
39 // Java layer: ms since Unix epoch, or -1 for null
40 int64_t ConvertTime(const base::TimeTicks& ticks,
41 const base::TimeTicks& start_ticks,
42 const base::Time& start_time) {
43 if (ticks.is_null() || start_ticks.is_null()) {
44 return -1;
45 }
46 DCHECK(!start_time.is_null());
47 return (start_time + (ticks - start_ticks)).ToJavaTime();
48 }
49
50 } // namespace
51
36 // Explicitly register static JNI functions. 52 // Explicitly register static JNI functions.
37 bool CronetUrlRequestAdapterRegisterJni(JNIEnv* env) { 53 bool CronetUrlRequestAdapterRegisterJni(JNIEnv* env) {
38 return RegisterNativesImpl(env); 54 return RegisterNativesImpl(env);
39 } 55 }
40 56
41 static jlong CreateRequestAdapter(JNIEnv* env, 57 static jlong CreateRequestAdapter(JNIEnv* env,
42 const JavaParamRef<jobject>& jurl_request, 58 const JavaParamRef<jobject>& jurl_request,
43 jlong jurl_request_context_adapter, 59 jlong jurl_request_context_adapter,
44 const JavaParamRef<jstring>& jurl_string, 60 const JavaParamRef<jstring>& jurl_string,
45 jint jpriority, 61 jint jpriority,
46 jboolean jdisable_cache, 62 jboolean jdisable_cache,
47 jboolean jdisable_connection_migration) { 63 jboolean jdisable_connection_migration,
64 jboolean jenable_metrics) {
48 CronetURLRequestContextAdapter* context_adapter = 65 CronetURLRequestContextAdapter* context_adapter =
49 reinterpret_cast<CronetURLRequestContextAdapter*>( 66 reinterpret_cast<CronetURLRequestContextAdapter*>(
50 jurl_request_context_adapter); 67 jurl_request_context_adapter);
51 DCHECK(context_adapter); 68 DCHECK(context_adapter);
52 69
53 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl_string)); 70 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl_string));
54 71
55 VLOG(1) << "New chromium network request_adapter: " 72 VLOG(1) << "New chromium network request_adapter: "
56 << url.possibly_invalid_spec(); 73 << url.possibly_invalid_spec();
57 74
58 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter( 75 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter(
59 context_adapter, env, jurl_request, url, 76 context_adapter, env, jurl_request, url,
60 static_cast<net::RequestPriority>(jpriority), jdisable_cache, 77 static_cast<net::RequestPriority>(jpriority), jdisable_cache,
61 jdisable_connection_migration); 78 jdisable_connection_migration, jenable_metrics);
62 79
63 return reinterpret_cast<jlong>(adapter); 80 return reinterpret_cast<jlong>(adapter);
64 } 81 }
65 82
66 CronetURLRequestAdapter::CronetURLRequestAdapter( 83 CronetURLRequestAdapter::CronetURLRequestAdapter(
67 CronetURLRequestContextAdapter* context, 84 CronetURLRequestContextAdapter* context,
68 JNIEnv* env, 85 JNIEnv* env,
69 jobject jurl_request, 86 jobject jurl_request,
70 const GURL& url, 87 const GURL& url,
71 net::RequestPriority priority, 88 net::RequestPriority priority,
72 jboolean jdisable_cache, 89 jboolean jdisable_cache,
73 jboolean jdisable_connection_migration) 90 jboolean jdisable_connection_migration,
91 jboolean jenable_metrics)
74 : context_(context), 92 : context_(context),
75 initial_url_(url), 93 initial_url_(url),
76 initial_priority_(priority), 94 initial_priority_(priority),
77 initial_method_("GET"), 95 initial_method_("GET"),
78 load_flags_(context->default_load_flags()) { 96 load_flags_(context->default_load_flags()),
97 enable_metrics_(jenable_metrics == JNI_TRUE) {
79 DCHECK(!context_->IsOnNetworkThread()); 98 DCHECK(!context_->IsOnNetworkThread());
80 owner_.Reset(env, jurl_request); 99 owner_.Reset(env, jurl_request);
81 if (jdisable_cache == JNI_TRUE) 100 if (jdisable_cache == JNI_TRUE)
82 load_flags_ |= net::LOAD_DISABLE_CACHE; 101 load_flags_ |= net::LOAD_DISABLE_CACHE;
83 if (jdisable_connection_migration == JNI_TRUE) 102 if (jdisable_connection_migration == JNI_TRUE)
84 load_flags_ |= net::LOAD_DISABLE_CONNECTION_MIGRATION; 103 load_flags_ |= net::LOAD_DISABLE_CONNECTION_MIGRATION;
85 } 104 }
86 105
87 CronetURLRequestAdapter::~CronetURLRequestAdapter() { 106 CronetURLRequestAdapter::~CronetURLRequestAdapter() {
88 DCHECK(context_->IsOnNetworkThread()); 107 DCHECK(context_->IsOnNetworkThread());
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 request->ContinueWithCertificate(nullptr, nullptr); 242 request->ContinueWithCertificate(nullptr, nullptr);
224 } 243 }
225 244
226 void CronetURLRequestAdapter::OnSSLCertificateError( 245 void CronetURLRequestAdapter::OnSSLCertificateError(
227 net::URLRequest* request, 246 net::URLRequest* request,
228 const net::SSLInfo& ssl_info, 247 const net::SSLInfo& ssl_info,
229 bool fatal) { 248 bool fatal) {
230 DCHECK(context_->IsOnNetworkThread()); 249 DCHECK(context_->IsOnNetworkThread());
231 request->Cancel(); 250 request->Cancel();
232 int net_error = net::MapCertStatusToNetError(ssl_info.cert_status); 251 int net_error = net::MapCertStatusToNetError(ssl_info.cert_status);
252 end_time_ = base::TimeTicks::Now();
233 JNIEnv* env = base::android::AttachCurrentThread(); 253 JNIEnv* env = base::android::AttachCurrentThread();
234 cronet::Java_CronetUrlRequest_onError( 254 cronet::Java_CronetUrlRequest_onError(
235 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error, 255 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error,
236 net::QUIC_NO_ERROR, 256 net::QUIC_NO_ERROR,
237 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(), 257 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(),
238 request->GetTotalReceivedBytes()); 258 request->GetTotalReceivedBytes());
239 } 259 }
240 260
241 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest* request, 261 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest* request,
242 int net_error) { 262 int net_error) {
(...skipping 22 matching lines...) Expand all
265 void CronetURLRequestAdapter::OnReadCompleted(net::URLRequest* request, 285 void CronetURLRequestAdapter::OnReadCompleted(net::URLRequest* request,
266 int bytes_read) { 286 int bytes_read) {
267 DCHECK(context_->IsOnNetworkThread()); 287 DCHECK(context_->IsOnNetworkThread());
268 288
269 if (bytes_read < 0) { 289 if (bytes_read < 0) {
270 ReportError(request, bytes_read); 290 ReportError(request, bytes_read);
271 return; 291 return;
272 } 292 }
273 293
274 if (bytes_read == 0) { 294 if (bytes_read == 0) {
295 end_time_ = base::TimeTicks::Now();
275 JNIEnv* env = base::android::AttachCurrentThread(); 296 JNIEnv* env = base::android::AttachCurrentThread();
276 cronet::Java_CronetUrlRequest_onSucceeded( 297 cronet::Java_CronetUrlRequest_onSucceeded(
277 env, owner_.obj(), url_request_->GetTotalReceivedBytes()); 298 env, owner_.obj(), url_request_->GetTotalReceivedBytes());
278 } else { 299 } else {
279 JNIEnv* env = base::android::AttachCurrentThread(); 300 JNIEnv* env = base::android::AttachCurrentThread();
280 cronet::Java_CronetUrlRequest_onReadCompleted( 301 cronet::Java_CronetUrlRequest_onReadCompleted(
281 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read, 302 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read,
282 read_buffer_->initial_position(), read_buffer_->initial_limit(), 303 read_buffer_->initial_position(), read_buffer_->initial_limit(),
283 request->GetTotalReceivedBytes()); 304 request->GetTotalReceivedBytes());
284 // Free the read buffer. This lets the Java ByteBuffer be freed, if the 305 // Free the read buffer. This lets the Java ByteBuffer be freed, if the
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 int result = url_request_->Read(read_buffer_.get(), buffer_size); 376 int result = url_request_->Read(read_buffer_.get(), buffer_size);
356 // If IO is pending, wait for the URLRequest to call OnReadCompleted. 377 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
357 if (result == net::ERR_IO_PENDING) 378 if (result == net::ERR_IO_PENDING)
358 return; 379 return;
359 380
360 OnReadCompleted(url_request_.get(), result); 381 OnReadCompleted(url_request_.get(), result);
361 } 382 }
362 383
363 void CronetURLRequestAdapter::DestroyOnNetworkThread(bool send_on_canceled) { 384 void CronetURLRequestAdapter::DestroyOnNetworkThread(bool send_on_canceled) {
364 DCHECK(context_->IsOnNetworkThread()); 385 DCHECK(context_->IsOnNetworkThread());
386 JNIEnv* env = base::android::AttachCurrentThread();
365 if (send_on_canceled) { 387 if (send_on_canceled) {
366 JNIEnv* env = base::android::AttachCurrentThread(); 388 end_time_ = base::TimeTicks::Now();
367 cronet::Java_CronetUrlRequest_onCanceled(env, owner_.obj()); 389 cronet::Java_CronetUrlRequest_onCanceled(env, owner_.obj());
368 } 390 }
391 MaybeReportMetrics(env);
369 delete this; 392 delete this;
370 } 393 }
371 394
372 void CronetURLRequestAdapter::ReportError(net::URLRequest* request, 395 void CronetURLRequestAdapter::ReportError(net::URLRequest* request,
373 int net_error) const { 396 int net_error) {
374 DCHECK_NE(net::ERR_IO_PENDING, net_error); 397 DCHECK_NE(net::ERR_IO_PENDING, net_error);
375 DCHECK_LT(net_error, 0); 398 DCHECK_LT(net_error, 0);
376 DCHECK_EQ(request, url_request_.get()); 399 DCHECK_EQ(request, url_request_.get());
377 400
378 net::NetErrorDetails net_error_details; 401 net::NetErrorDetails net_error_details;
379 url_request_->PopulateNetErrorDetails(&net_error_details); 402 url_request_->PopulateNetErrorDetails(&net_error_details);
380 VLOG(1) << "Error " << net::ErrorToString(net_error) 403 VLOG(1) << "Error " << net::ErrorToString(net_error)
381 << " on chromium request: " << initial_url_.possibly_invalid_spec(); 404 << " on chromium request: " << initial_url_.possibly_invalid_spec();
405 end_time_ = base::TimeTicks::Now();
382 JNIEnv* env = base::android::AttachCurrentThread(); 406 JNIEnv* env = base::android::AttachCurrentThread();
383 cronet::Java_CronetUrlRequest_onError( 407 cronet::Java_CronetUrlRequest_onError(
384 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error, 408 env, owner_.obj(), NetErrorToUrlRequestError(net_error), net_error,
385 net_error_details.quic_connection_error, 409 net_error_details.quic_connection_error,
386 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(), 410 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj(),
387 request->GetTotalReceivedBytes()); 411 request->GetTotalReceivedBytes());
388 } 412 }
389 413
414 void CronetURLRequestAdapter::MaybeReportMetrics(JNIEnv* env) const {
xunjieli 2016/10/01 13:43:49 I don't quite understand the need to populate |end
mgersh 2016/10/04 21:14:58 On my test device it's usually off by 1ms, sometim
415 if (!enable_metrics_) {
416 return;
417 }
418 net::LoadTimingInfo metrics;
419 url_request_->GetLoadTimingInfo(&metrics);
420 base::Time start_time = metrics.request_start_time;
421 base::TimeTicks start_ticks = metrics.request_start;
422 Java_CronetUrlRequest_onMetricsCollected(
423 env, owner_.obj(), ConvertTime(start_ticks, start_ticks, start_time),
424 ConvertTime(metrics.connect_timing.dns_start, start_ticks, start_time),
425 ConvertTime(metrics.connect_timing.dns_end, start_ticks, start_time),
426 ConvertTime(metrics.connect_timing.connect_start, start_ticks,
427 start_time),
428 ConvertTime(metrics.connect_timing.connect_end, start_ticks, start_time),
429 ConvertTime(metrics.connect_timing.ssl_start, start_ticks, start_time),
430 ConvertTime(metrics.connect_timing.ssl_end, start_ticks, start_time),
431 ConvertTime(metrics.send_start, start_ticks, start_time),
432 ConvertTime(metrics.send_end, start_ticks, start_time),
433 ConvertTime(metrics.push_start, start_ticks, start_time),
434 ConvertTime(metrics.push_end, start_ticks, start_time),
435 ConvertTime(metrics.receive_headers_end, start_ticks, start_time),
436 ConvertTime(end_time_, start_ticks, start_time),
437 // TODO(mgersh): report total bytes sent
438 metrics.socket_reused, 0, url_request_->GetTotalReceivedBytes());
439 }
440
390 net::URLRequest* CronetURLRequestAdapter::GetURLRequestForTesting() { 441 net::URLRequest* CronetURLRequestAdapter::GetURLRequestForTesting() {
391 return url_request_.get(); 442 return url_request_.get();
392 } 443 }
393 444
394 } // namespace cronet 445 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698