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

Side by Side Diff: components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java

Issue 2844803002: [Cronet] Make metrics reporting happen after terminal callbacks. (Closed)
Patch Set: address comments Created 3 years, 7 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 package org.chromium.net.impl; 5 package org.chromium.net.impl;
6 6
7 import org.chromium.base.Log; 7 import org.chromium.base.Log;
8 import org.chromium.base.VisibleForTesting; 8 import org.chromium.base.VisibleForTesting;
9 import org.chromium.base.annotations.CalledByNative; 9 import org.chromium.base.annotations.CalledByNative;
10 import org.chromium.base.annotations.JNIAdditionalImport; 10 import org.chromium.base.annotations.JNIAdditionalImport;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 @JNIAdditionalImport(VersionSafeCallbacks.class) 44 @JNIAdditionalImport(VersionSafeCallbacks.class)
45 @VisibleForTesting 45 @VisibleForTesting
46 public final class CronetUrlRequest extends UrlRequestBase { 46 public final class CronetUrlRequest extends UrlRequestBase {
47 private final boolean mAllowDirectExecutor; 47 private final boolean mAllowDirectExecutor;
48 48
49 /* Native adapter object, owned by UrlRequest. */ 49 /* Native adapter object, owned by UrlRequest. */
50 @GuardedBy("mUrlRequestAdapterLock") 50 @GuardedBy("mUrlRequestAdapterLock")
51 private long mUrlRequestAdapter; 51 private long mUrlRequestAdapter;
52 52
53 @GuardedBy("mUrlRequestAdapterLock") 53 @GuardedBy("mUrlRequestAdapterLock")
54 private boolean mStarted = false; 54 private boolean mStarted;
55 @GuardedBy("mUrlRequestAdapterLock") 55 @GuardedBy("mUrlRequestAdapterLock")
56 private boolean mWaitingOnRedirect = false; 56 private boolean mWaitingOnRedirect;
57 @GuardedBy("mUrlRequestAdapterLock") 57 @GuardedBy("mUrlRequestAdapterLock")
58 private boolean mWaitingOnRead = false; 58 private boolean mWaitingOnRead;
59 @GuardedBy("mUrlRequestAdapterLock")
60 private RequestFinishedInfo.Metrics mMetrics;
61 59
62 /* 60 /*
63 * Synchronize access to mUrlRequestAdapter, mStarted, mWaitingOnRedirect, 61 * Synchronize access to mUrlRequestAdapter, mStarted, mWaitingOnRedirect,
64 * and mWaitingOnRead. 62 * and mWaitingOnRead.
65 */ 63 */
66 private final Object mUrlRequestAdapterLock = new Object(); 64 private final Object mUrlRequestAdapterLock = new Object();
67 private final CronetUrlRequestContext mRequestContext; 65 private final CronetUrlRequestContext mRequestContext;
68 private final Executor mExecutor; 66 private final Executor mExecutor;
69 67
70 /* 68 /*
71 * URL chain contains the URL currently being requested, and 69 * URL chain contains the URL currently being requested, and
72 * all URLs previously requested. New URLs are added before 70 * all URLs previously requested. New URLs are added before
73 * mCallback.onRedirectReceived is called. 71 * mCallback.onRedirectReceived is called.
74 */ 72 */
75 private final List<String> mUrlChain = new ArrayList<String>(); 73 private final List<String> mUrlChain = new ArrayList<String>();
76 private long mReceivedByteCountFromRedirects; 74 private long mReceivedByteCountFromRedirects;
77 75
78 private final VersionSafeCallbacks.UrlRequestCallback mCallback; 76 private final VersionSafeCallbacks.UrlRequestCallback mCallback;
79 private final String mInitialUrl; 77 private final String mInitialUrl;
80 private final int mPriority; 78 private final int mPriority;
81 private String mInitialMethod; 79 private String mInitialMethod;
82 private final HeadersList mRequestHeaders = new HeadersList(); 80 private final HeadersList mRequestHeaders = new HeadersList();
83 private final Collection<Object> mRequestAnnotations; 81 private final Collection<Object> mRequestAnnotations;
84 @RequestFinishedInfoImpl.FinishedReason
85 private int mFinishedReason;
86 private CronetException mException;
87 private final boolean mDisableCache; 82 private final boolean mDisableCache;
88 private final boolean mDisableConnectionMigration; 83 private final boolean mDisableConnectionMigration;
89 84
90 private CronetUploadDataStream mUploadDataStream; 85 private CronetUploadDataStream mUploadDataStream;
91 86
92 private UrlResponseInfoImpl mResponseInfo; 87 private UrlResponseInfoImpl mResponseInfo;
93 88
89 // These three should only be updated once with mUrlRequestAdapterLock held. They are read on
90 // UrlRequest.Callback's and RequestFinishedInfo.Listener's executors after the last update.
91 @RequestFinishedInfoImpl.FinishedReason
92 private int mFinishedReason;
93 private CronetException mException;
94 private CronetMetrics mMetrics;
95
94 /* 96 /*
95 * Listener callback is repeatedly invoked when each read is completed, so i t 97 * Listener callback is repeatedly invoked when each read is completed, so i t
96 * is cached as a member variable. 98 * is cached as a member variable.
97 */ 99 */
98 private OnReadCompletedRunnable mOnReadCompletedTask; 100 private OnReadCompletedRunnable mOnReadCompletedTask;
99 101
102 @GuardedBy("mUrlRequestAdapterLock")
100 private Runnable mOnDestroyedCallbackForTesting; 103 private Runnable mOnDestroyedCallbackForTesting;
101 104
102 private static final class HeadersList extends ArrayList<Map.Entry<String, S tring>> {} 105 private static final class HeadersList extends ArrayList<Map.Entry<String, S tring>> {}
103 106
104 private final class OnReadCompletedRunnable implements Runnable { 107 private final class OnReadCompletedRunnable implements Runnable {
105 // Buffer passed back from current invocation of onReadCompleted. 108 // Buffer passed back from current invocation of onReadCompleted.
106 ByteBuffer mByteBuffer; 109 ByteBuffer mByteBuffer;
107 110
108 @Override 111 @Override
109 public void run() { 112 public void run() {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 return; 230 return;
228 } 231 }
229 mUploadDataStream.attachNativeAdapterToRequest(m UrlRequestAdapter); 232 mUploadDataStream.attachNativeAdapterToRequest(m UrlRequestAdapter);
230 startInternalLocked(); 233 startInternalLocked();
231 } 234 }
232 } 235 }
233 }); 236 });
234 return; 237 return;
235 } 238 }
236 } catch (RuntimeException e) { 239 } catch (RuntimeException e) {
237 // If there's an exception, cleanup and then throw the 240 // If there's an exception, cleanup and then throw the exception to the caller.
238 // exception to the caller. 241 // start() is synchronized so we do not acquire mUrlRequestAdapt erLock here.
239 destroyRequestAdapter(false); 242 destroyRequestAdapterLocked(RequestFinishedInfo.FAILED);
240 throw e; 243 throw e;
241 } 244 }
242 mStarted = true; 245 mStarted = true;
243 startInternalLocked(); 246 startInternalLocked();
244 } 247 }
245 } 248 }
246 249
247 /* 250 /*
248 * Starts fully configured request. Could execute on UploadDataProvider exec utor. 251 * Starts fully configured request. Could execute on UploadDataProvider exec utor.
249 * Caller is expected to ensure that request isn't canceled and mUrlRequestA dapter is valid. 252 * Caller is expected to ensure that request isn't canceled and mUrlRequestA dapter is valid.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 } 294 }
292 } 295 }
293 } 296 }
294 297
295 @Override 298 @Override
296 public void cancel() { 299 public void cancel() {
297 synchronized (mUrlRequestAdapterLock) { 300 synchronized (mUrlRequestAdapterLock) {
298 if (isDoneLocked() || !mStarted) { 301 if (isDoneLocked() || !mStarted) {
299 return; 302 return;
300 } 303 }
301 destroyRequestAdapter(true); 304 destroyRequestAdapterLocked(RequestFinishedInfo.CANCELED);
302 } 305 }
303 } 306 }
304 307
305 @Override 308 @Override
306 public boolean isDone() { 309 public boolean isDone() {
307 synchronized (mUrlRequestAdapterLock) { 310 synchronized (mUrlRequestAdapterLock) {
308 return isDoneLocked(); 311 return isDoneLocked();
309 } 312 }
310 } 313 }
311 314
(...skipping 16 matching lines...) Expand all
328 @Override 331 @Override
329 public void run() { 332 public void run() {
330 listener.onStatus(UrlRequest.Status.INVALID); 333 listener.onStatus(UrlRequest.Status.INVALID);
331 } 334 }
332 }; 335 };
333 postTaskToExecutor(task); 336 postTaskToExecutor(task);
334 } 337 }
335 338
336 @VisibleForTesting 339 @VisibleForTesting
337 public void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackFor Testing) { 340 public void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackFor Testing) {
338 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; 341 synchronized (mUrlRequestAdapterLock) {
342 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting;
343 }
339 } 344 }
340 345
341 @VisibleForTesting 346 @VisibleForTesting
342 public void setOnDestroyedUploadCallbackForTesting( 347 public void setOnDestroyedUploadCallbackForTesting(
343 Runnable onDestroyedUploadCallbackForTesting) { 348 Runnable onDestroyedUploadCallbackForTesting) {
344 mUploadDataStream.setOnDestroyedCallbackForTesting(onDestroyedUploadCall backForTesting); 349 mUploadDataStream.setOnDestroyedCallbackForTesting(onDestroyedUploadCall backForTesting);
345 } 350 }
346 351
347 @VisibleForTesting 352 @VisibleForTesting
348 public long getUrlRequestAdapterForTesting() { 353 public long getUrlRequestAdapterForTesting() {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 408 }
404 409
405 private void checkNotStarted() { 410 private void checkNotStarted() {
406 synchronized (mUrlRequestAdapterLock) { 411 synchronized (mUrlRequestAdapterLock) {
407 if (mStarted || isDoneLocked()) { 412 if (mStarted || isDoneLocked()) {
408 throw new IllegalStateException("Request is already started."); 413 throw new IllegalStateException("Request is already started.");
409 } 414 }
410 } 415 }
411 } 416 }
412 417
413 private void destroyRequestAdapter(boolean sendOnCanceled) {
414 synchronized (mUrlRequestAdapterLock) {
415 if (mUrlRequestAdapter == 0) {
416 return;
417 }
418 nativeDestroy(mUrlRequestAdapter, sendOnCanceled);
419 mRequestContext.onRequestDestroyed();
420 mUrlRequestAdapter = 0;
421 if (mOnDestroyedCallbackForTesting != null) {
422 mOnDestroyedCallbackForTesting.run();
423 }
424 }
425 }
426
427 /** 418 /**
419 * Helper method to set final status of CronetUrlRequest and clean up the
420 * native request adapter.
421 */
422 @GuardedBy("mUrlRequestAdapterLock")
423 private void destroyRequestAdapterLocked(
424 @RequestFinishedInfoImpl.FinishedReason int finishedReason) {
425 assert mException == null || finishedReason == RequestFinishedInfo.FAILE D;
426 mFinishedReason = finishedReason;
427 if (mUrlRequestAdapter == 0) {
428 return;
429 }
430 mRequestContext.onRequestDestroyed();
431 // Posts a task to destroy the native adapter.
432 nativeDestroy(mUrlRequestAdapter, finishedReason == RequestFinishedInfo. CANCELED);
433 mUrlRequestAdapter = 0;
434 }
435
436 /**
428 * If callback method throws an exception, request gets canceled 437 * If callback method throws an exception, request gets canceled
429 * and exception is reported via onFailed listener callback. 438 * and exception is reported via onFailed listener callback.
430 * Only called on the Executor. 439 * Only called on the Executor.
431 */ 440 */
432 private void onCallbackException(Exception e) { 441 private void onCallbackException(Exception e) {
433 CallbackException requestError = 442 CallbackException requestError =
434 new CallbackExceptionImpl("Exception received from UrlRequest.Ca llback", e); 443 new CallbackExceptionImpl("Exception received from UrlRequest.Ca llback", e);
435 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in CalledByNative meth od", e); 444 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in CalledByNative meth od", e);
436 failWithException(requestError); 445 failWithException(requestError);
437 } 446 }
438 447
439 /** 448 /**
440 * Called when UploadDataProvider encounters an error. 449 * Called when UploadDataProvider encounters an error.
441 */ 450 */
442 void onUploadException(Throwable e) { 451 void onUploadException(Throwable e) {
443 CallbackException uploadError = 452 CallbackException uploadError =
444 new CallbackExceptionImpl("Exception received from UploadDataPro vider", e); 453 new CallbackExceptionImpl("Exception received from UploadDataPro vider", e);
445 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in upload method", e); 454 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in upload method", e);
446 failWithException(uploadError); 455 failWithException(uploadError);
447 } 456 }
448 457
449 /** 458 /**
450 * Fails the request with an exception. Can be called on any thread. 459 * Fails the request with an exception on any thread.
451 */ 460 */
452 private void failWithException(final CronetException exception) { 461 private void failWithException(final CronetException exception) {
453 mException = exception;
454 synchronized (mUrlRequestAdapterLock) { 462 synchronized (mUrlRequestAdapterLock) {
455 if (isDoneLocked()) { 463 if (isDoneLocked()) {
456 return; 464 return;
457 } 465 }
458 destroyRequestAdapter(false); 466 assert mException == null;
467 mException = exception;
468 destroyRequestAdapterLocked(RequestFinishedInfo.FAILED);
459 } 469 }
460 Runnable task = new Runnable() { 470 // onFailed will be invoked from onNativeAdapterDestroyed() to ensure me trics collection.
461 @Override
462 public void run() {
463 try {
464 mCallback.onFailed(CronetUrlRequest.this, mResponseInfo, exc eption);
465 } catch (Exception e) {
466 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onFaile d method", e);
467 }
468 }
469 };
470 try {
471 mExecutor.execute(task);
472 } catch (RejectedExecutionException e) {
473 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", e);
474 }
475 } 471 }
476 472
477 //////////////////////////////////////////////// 473 ////////////////////////////////////////////////
478 // Private methods called by the native code. 474 // Private methods called by the native code.
479 // Always called on network thread. 475 // Always called on network thread.
480 //////////////////////////////////////////////// 476 ////////////////////////////////////////////////
481 477
482 /** 478 /**
483 * Called before following redirects. The redirect will only be followed if 479 * Called before following redirects. The redirect will only be followed if
484 * {@link #followRedirect()} is called. If the redirect response has a body, it will be ignored. 480 * {@link #followRedirect()} is called. If the redirect response has a body, it will be ignored.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 589
594 /** 590 /**
595 * Called when request is completed successfully, no callbacks will be 591 * Called when request is completed successfully, no callbacks will be
596 * called afterwards. 592 * called afterwards.
597 * 593 *
598 * @param receivedByteCount number of bytes received. 594 * @param receivedByteCount number of bytes received.
599 */ 595 */
600 @SuppressWarnings("unused") 596 @SuppressWarnings("unused")
601 @CalledByNative 597 @CalledByNative
602 private void onSucceeded(long receivedByteCount) { 598 private void onSucceeded(long receivedByteCount) {
603 mFinishedReason = RequestFinishedInfo.SUCCEEDED;
604 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + rec eivedByteCount); 599 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + rec eivedByteCount);
605 Runnable task = new Runnable() { 600 Runnable task = new Runnable() {
606 @Override 601 @Override
607 public void run() { 602 public void run() {
608 synchronized (mUrlRequestAdapterLock) { 603 synchronized (mUrlRequestAdapterLock) {
609 if (isDoneLocked()) { 604 if (isDoneLocked()) {
610 return; 605 return;
611 } 606 }
612 // Destroy adapter first, so request context could be shut 607 // Destroy adapter first, so request context could be shut
613 // down from the listener. 608 // down from the listener.
614 destroyRequestAdapter(false); 609 destroyRequestAdapterLocked(RequestFinishedInfo.SUCCEEDED);
615 } 610 }
616 try { 611 try {
617 mCallback.onSucceeded(CronetUrlRequest.this, mResponseInfo); 612 mCallback.onSucceeded(CronetUrlRequest.this, mResponseInfo);
613 maybeReportMetrics();
618 } catch (Exception e) { 614 } catch (Exception e) {
619 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCompl ete method", e); 615 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onSucce eded method", e);
620 } 616 }
621 } 617 }
622 }; 618 };
623 postTaskToExecutor(task); 619 postTaskToExecutor(task);
624 } 620 }
625 621
626 /** 622 /**
627 * Called when error has occured, no callbacks will be called afterwards. 623 * Called when error has occured, no callbacks will be called afterwards.
628 * 624 *
629 * @param errorCode Error code represented by {@code UrlRequestError} that s hould be mapped 625 * @param errorCode Error code represented by {@code UrlRequestError} that s hould be mapped
630 * to one of {@link NetworkException#ERROR_HOSTNAME_NOT_RES OLVED 626 * to one of {@link NetworkException#ERROR_HOSTNAME_NOT_RES OLVED
631 * NetworkException.ERROR_*}. 627 * NetworkException.ERROR_*}.
632 * @param nativeError native net error code. 628 * @param nativeError native net error code.
633 * @param errorString textual representation of the error code. 629 * @param errorString textual representation of the error code.
634 * @param receivedByteCount number of bytes received. 630 * @param receivedByteCount number of bytes received.
635 */ 631 */
636 @SuppressWarnings("unused") 632 @SuppressWarnings("unused")
637 @CalledByNative 633 @CalledByNative
638 private void onError(int errorCode, int nativeError, int nativeQuicError, St ring errorString, 634 private void onError(int errorCode, int nativeError, int nativeQuicError, St ring errorString,
639 long receivedByteCount) { 635 long receivedByteCount) {
640 mFinishedReason = RequestFinishedInfo.FAILED;
641 if (mResponseInfo != null) { 636 if (mResponseInfo != null) {
642 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + receivedByteCount); 637 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + receivedByteCount);
643 } 638 }
644 if (errorCode == NetworkException.ERROR_QUIC_PROTOCOL_FAILED) { 639 if (errorCode == NetworkException.ERROR_QUIC_PROTOCOL_FAILED) {
645 failWithException(new QuicExceptionImpl( 640 failWithException(new QuicExceptionImpl(
646 "Exception in CronetUrlRequest: " + errorString, nativeError , nativeQuicError)); 641 "Exception in CronetUrlRequest: " + errorString, nativeError , nativeQuicError));
647 } else { 642 } else {
648 int javaError = mapUrlRequestErrorToApiErrorCode(errorCode); 643 int javaError = mapUrlRequestErrorToApiErrorCode(errorCode);
649 failWithException(new NetworkExceptionImpl( 644 failWithException(new NetworkExceptionImpl(
650 "Exception in CronetUrlRequest: " + errorString, javaError, nativeError)); 645 "Exception in CronetUrlRequest: " + errorString, javaError, nativeError));
651 } 646 }
652 } 647 }
653 648
654 /** 649 /**
655 * Called when request is canceled, no callbacks will be called afterwards. 650 * Called when request is canceled, no callbacks will be called afterwards.
656 */ 651 */
657 @SuppressWarnings("unused") 652 @SuppressWarnings("unused")
658 @CalledByNative 653 @CalledByNative
659 private void onCanceled() { 654 private void onCanceled() {
660 mFinishedReason = RequestFinishedInfo.CANCELED;
661 Runnable task = new Runnable() { 655 Runnable task = new Runnable() {
662 @Override 656 @Override
663 public void run() { 657 public void run() {
664 try { 658 try {
665 mCallback.onCanceled(CronetUrlRequest.this, mResponseInfo); 659 mCallback.onCanceled(CronetUrlRequest.this, mResponseInfo);
660 maybeReportMetrics();
666 } catch (Exception e) { 661 } catch (Exception e) {
667 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance led method", e); 662 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance led method", e);
668 } 663 }
669 } 664 }
670 }; 665 };
671 postTaskToExecutor(task); 666 postTaskToExecutor(task);
672 } 667 }
673 668
674 /** 669 /**
675 * Called by the native code when request status is fetched from the 670 * Called by the native code when request status is fetched from the
676 * native stack. 671 * native stack.
677 */ 672 */
678 @SuppressWarnings("unused") 673 @SuppressWarnings("unused")
679 @CalledByNative 674 @CalledByNative
680 private void onStatus( 675 private void onStatus(
681 final VersionSafeCallbacks.UrlRequestStatusListener listener, final int loadState) { 676 final VersionSafeCallbacks.UrlRequestStatusListener listener, final int loadState) {
682 Runnable task = new Runnable() { 677 Runnable task = new Runnable() {
683 @Override 678 @Override
684 public void run() { 679 public void run() {
685 listener.onStatus(convertLoadState(loadState)); 680 listener.onStatus(convertLoadState(loadState));
686 } 681 }
687 }; 682 };
688 postTaskToExecutor(task); 683 postTaskToExecutor(task);
689 } 684 }
690 685
691 /** 686 /**
692 * Called by the native code to report metrics. 687 * Called by the native code on the network thread to report metrics. Happen s before
688 * onSucceeded, onError and onCanceled.
693 */ 689 */
694 @SuppressWarnings("unused") 690 @SuppressWarnings("unused")
695 @CalledByNative 691 @CalledByNative
696 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d nsEndMs, 692 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d nsEndMs,
697 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd Ms, 693 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd Ms,
698 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE ndMs, 694 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE ndMs,
699 long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount, 695 long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount,
700 long receivedByteCount) { 696 long receivedByteCount) {
701 synchronized (mUrlRequestAdapterLock) { 697 synchronized (mUrlRequestAdapterLock) {
702 if (mMetrics != null) { 698 if (mMetrics != null) {
703 throw new IllegalStateException("Metrics collection should only happen once."); 699 throw new IllegalStateException("Metrics collection should only happen once.");
704 } 700 }
705 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c onnectStartMs, 701 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c onnectStartMs,
706 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE ndMs, pushStartMs, 702 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE ndMs, pushStartMs,
707 pushEndMs, responseStartMs, requestEndMs, socketReused, sent ByteCount, 703 pushEndMs, responseStartMs, requestEndMs, socketReused, sent ByteCount,
708 receivedByteCount); 704 receivedByteCount);
709 } 705 }
710 mRequestContext.reportFinished(getRequestFinishedInfo()); 706 // Metrics are reported to RequestFinishedListener when the final UrlReq uest.Callback has
707 // been invoked.
711 } 708 }
712 709
713 private RequestFinishedInfo getRequestFinishedInfo() { 710 /**
714 return new RequestFinishedInfoImpl(mInitialUrl, mRequestAnnotations, mMe trics, 711 * Called when the native adapter is destroyed.
715 mFinishedReason, mResponseInfo, mException); 712 */
713 @SuppressWarnings("unused")
714 @CalledByNative
715 private void onNativeAdapterDestroyed() {
716 synchronized (mUrlRequestAdapterLock) {
717 if (mOnDestroyedCallbackForTesting != null) {
718 mOnDestroyedCallbackForTesting.run();
719 }
720 // mException is set when an error is encountered (in native code vi a onError or in
721 // Java code). If mException is not null, notify the mCallback and r eport metrics.
722 if (mException == null) {
723 return;
724 }
725 }
726 Runnable task = new Runnable() {
727 @Override
728 public void run() {
729 try {
730 mCallback.onFailed(CronetUrlRequest.this, mResponseInfo, mEx ception);
731 maybeReportMetrics();
732 } catch (Exception e) {
733 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onFaile d method", e);
734 }
735 }
736 };
737 try {
738 mExecutor.execute(task);
739 } catch (RejectedExecutionException e) {
740 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", e);
741 }
716 } 742 }
717 743
718 /** Enforces prohibition of direct execution. */ 744 /** Enforces prohibition of direct execution. */
719 void checkCallingThread() { 745 void checkCallingThread() {
720 if (!mAllowDirectExecutor && mRequestContext.isNetworkThread(Thread.curr entThread())) { 746 if (!mAllowDirectExecutor && mRequestContext.isNetworkThread(Thread.curr entThread())) {
721 throw new InlineExecutionProhibitedException(); 747 throw new InlineExecutionProhibitedException();
722 } 748 }
723 } 749 }
724 750
725 private int mapUrlRequestErrorToApiErrorCode(int errorCode) { 751 private int mapUrlRequestErrorToApiErrorCode(int errorCode) {
(...skipping 19 matching lines...) Expand all
745 case UrlRequestError.QUIC_PROTOCOL_FAILED: 771 case UrlRequestError.QUIC_PROTOCOL_FAILED:
746 return NetworkException.ERROR_QUIC_PROTOCOL_FAILED; 772 return NetworkException.ERROR_QUIC_PROTOCOL_FAILED;
747 case UrlRequestError.OTHER: 773 case UrlRequestError.OTHER:
748 return NetworkException.ERROR_OTHER; 774 return NetworkException.ERROR_OTHER;
749 default: 775 default:
750 Log.e(CronetUrlRequestContext.LOG_TAG, "Unknown error code: " + errorCode); 776 Log.e(CronetUrlRequestContext.LOG_TAG, "Unknown error code: " + errorCode);
751 return errorCode; 777 return errorCode;
752 } 778 }
753 } 779 }
754 780
781 // Maybe report metrics. This method should only be called on Callback's exe cutor thread and
782 // after Callback's onSucceeded, onFailed and onCanceled.
783 private void maybeReportMetrics() {
784 if (mMetrics != null) {
785 mRequestContext.reportFinished(new RequestFinishedInfoImpl(mInitialU rl,
786 mRequestAnnotations, mMetrics, mFinishedReason, mResponseInf o, mException));
787 }
788 }
789
755 // Native methods are implemented in cronet_url_request_adapter.cc. 790 // Native methods are implemented in cronet_url_request_adapter.cc.
756 791
757 private native long nativeCreateRequestAdapter(long urlRequestContextAdapter , String url, 792 private native long nativeCreateRequestAdapter(long urlRequestContextAdapter , String url,
758 int priority, boolean disableCache, boolean disableConnectionMigrati on, 793 int priority, boolean disableCache, boolean disableConnectionMigrati on,
759 boolean enableMetrics); 794 boolean enableMetrics);
760 795
761 @NativeClassQualifiedName("CronetURLRequestAdapter") 796 @NativeClassQualifiedName("CronetURLRequestAdapter")
762 private native boolean nativeSetHttpMethod(long nativePtr, String method); 797 private native boolean nativeSetHttpMethod(long nativePtr, String method);
763 798
764 @NativeClassQualifiedName("CronetURLRequestAdapter") 799 @NativeClassQualifiedName("CronetURLRequestAdapter")
765 private native boolean nativeAddRequestHeader(long nativePtr, String name, S tring value); 800 private native boolean nativeAddRequestHeader(long nativePtr, String name, S tring value);
766 801
767 @NativeClassQualifiedName("CronetURLRequestAdapter") 802 @NativeClassQualifiedName("CronetURLRequestAdapter")
768 private native void nativeStart(long nativePtr); 803 private native void nativeStart(long nativePtr);
769 804
770 @NativeClassQualifiedName("CronetURLRequestAdapter") 805 @NativeClassQualifiedName("CronetURLRequestAdapter")
771 private native void nativeFollowDeferredRedirect(long nativePtr); 806 private native void nativeFollowDeferredRedirect(long nativePtr);
772 807
773 @NativeClassQualifiedName("CronetURLRequestAdapter") 808 @NativeClassQualifiedName("CronetURLRequestAdapter")
774 private native boolean nativeReadData( 809 private native boolean nativeReadData(
775 long nativePtr, ByteBuffer byteBuffer, int position, int capacity); 810 long nativePtr, ByteBuffer byteBuffer, int position, int capacity);
776 811
777 @NativeClassQualifiedName("CronetURLRequestAdapter") 812 @NativeClassQualifiedName("CronetURLRequestAdapter")
778 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled); 813 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled);
779 814
780 @NativeClassQualifiedName("CronetURLRequestAdapter") 815 @NativeClassQualifiedName("CronetURLRequestAdapter")
781 private native void nativeGetStatus( 816 private native void nativeGetStatus(
782 long nativePtr, VersionSafeCallbacks.UrlRequestStatusListener listen er); 817 long nativePtr, VersionSafeCallbacks.UrlRequestStatusListener listen er);
783 } 818 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698