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

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: self 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 executor's and RequestFinishedListener's thread after the last update.
mgersh 2017/05/02 18:21:12 nits: UrlRequest, RequestFinishedInfo.Listener. T
xunjieli 2017/05/02 23:30:23 Done.
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 // The onFailed callback will be invoked from onNativeAdapterDestroyed() to ensure metrics
461 @Override 471 // collection
mgersh 2017/05/02 18:21:13 nit: missing period at the end
xunjieli 2017/05/02 23:30:23 Done.
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 } 472 }
476 473
477 //////////////////////////////////////////////// 474 ////////////////////////////////////////////////
478 // Private methods called by the native code. 475 // Private methods called by the native code.
479 // Always called on network thread. 476 // Always called on network thread.
480 //////////////////////////////////////////////// 477 ////////////////////////////////////////////////
481 478
482 /** 479 /**
483 * Called before following redirects. The redirect will only be followed if 480 * 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. 481 * {@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 590
594 /** 591 /**
595 * Called when request is completed successfully, no callbacks will be 592 * Called when request is completed successfully, no callbacks will be
596 * called afterwards. 593 * called afterwards.
597 * 594 *
598 * @param receivedByteCount number of bytes received. 595 * @param receivedByteCount number of bytes received.
599 */ 596 */
600 @SuppressWarnings("unused") 597 @SuppressWarnings("unused")
601 @CalledByNative 598 @CalledByNative
602 private void onSucceeded(long receivedByteCount) { 599 private void onSucceeded(long receivedByteCount) {
603 mFinishedReason = RequestFinishedInfo.SUCCEEDED;
604 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + rec eivedByteCount); 600 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + rec eivedByteCount);
605 Runnable task = new Runnable() { 601 Runnable task = new Runnable() {
606 @Override 602 @Override
607 public void run() { 603 public void run() {
608 synchronized (mUrlRequestAdapterLock) { 604 synchronized (mUrlRequestAdapterLock) {
609 if (isDoneLocked()) { 605 if (isDoneLocked()) {
610 return; 606 return;
611 } 607 }
612 // Destroy adapter first, so request context could be shut 608 // Destroy adapter first, so request context could be shut
613 // down from the listener. 609 // down from the listener.
614 destroyRequestAdapter(false); 610 destroyRequestAdapterLocked(RequestFinishedInfo.SUCCEEDED);
615 } 611 }
616 try { 612 try {
617 mCallback.onSucceeded(CronetUrlRequest.this, mResponseInfo); 613 mCallback.onSucceeded(CronetUrlRequest.this, mResponseInfo);
614 maybeReportMetrics();
618 } catch (Exception e) { 615 } catch (Exception e) {
619 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCompl ete method", e); 616 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onSucce eded method", e);
620 } 617 }
621 } 618 }
622 }; 619 };
623 postTaskToExecutor(task); 620 postTaskToExecutor(task);
624 } 621 }
625 622
626 /** 623 /**
627 * Called when error has occured, no callbacks will be called afterwards. 624 * Called when error has occured, no callbacks will be called afterwards.
628 * 625 *
629 * @param errorCode Error code represented by {@code UrlRequestError} that s hould be mapped 626 * @param errorCode Error code represented by {@code UrlRequestError} that s hould be mapped
630 * to one of {@link NetworkException#ERROR_HOSTNAME_NOT_RES OLVED 627 * to one of {@link NetworkException#ERROR_HOSTNAME_NOT_RES OLVED
631 * NetworkException.ERROR_*}. 628 * NetworkException.ERROR_*}.
632 * @param nativeError native net error code. 629 * @param nativeError native net error code.
633 * @param errorString textual representation of the error code. 630 * @param errorString textual representation of the error code.
634 * @param receivedByteCount number of bytes received. 631 * @param receivedByteCount number of bytes received.
635 */ 632 */
636 @SuppressWarnings("unused") 633 @SuppressWarnings("unused")
637 @CalledByNative 634 @CalledByNative
638 private void onError(int errorCode, int nativeError, int nativeQuicError, St ring errorString, 635 private void onError(int errorCode, int nativeError, int nativeQuicError, St ring errorString,
639 long receivedByteCount) { 636 long receivedByteCount) {
640 mFinishedReason = RequestFinishedInfo.FAILED;
641 if (mResponseInfo != null) { 637 if (mResponseInfo != null) {
642 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + receivedByteCount); 638 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + receivedByteCount);
643 } 639 }
644 if (errorCode == NetworkException.ERROR_QUIC_PROTOCOL_FAILED) { 640 if (errorCode == NetworkException.ERROR_QUIC_PROTOCOL_FAILED) {
645 failWithException(new QuicExceptionImpl( 641 failWithException(new QuicExceptionImpl(
646 "Exception in CronetUrlRequest: " + errorString, nativeError , nativeQuicError)); 642 "Exception in CronetUrlRequest: " + errorString, nativeError , nativeQuicError));
647 } else { 643 } else {
648 int javaError = mapUrlRequestErrorToApiErrorCode(errorCode); 644 int javaError = mapUrlRequestErrorToApiErrorCode(errorCode);
649 failWithException(new NetworkExceptionImpl( 645 failWithException(new NetworkExceptionImpl(
650 "Exception in CronetUrlRequest: " + errorString, javaError, nativeError)); 646 "Exception in CronetUrlRequest: " + errorString, javaError, nativeError));
651 } 647 }
652 } 648 }
653 649
654 /** 650 /**
655 * Called when request is canceled, no callbacks will be called afterwards. 651 * Called when request is canceled, no callbacks will be called afterwards.
656 */ 652 */
657 @SuppressWarnings("unused") 653 @SuppressWarnings("unused")
658 @CalledByNative 654 @CalledByNative
659 private void onCanceled() { 655 private void onCanceled() {
660 mFinishedReason = RequestFinishedInfo.CANCELED;
661 Runnable task = new Runnable() { 656 Runnable task = new Runnable() {
662 @Override 657 @Override
663 public void run() { 658 public void run() {
664 try { 659 try {
665 mCallback.onCanceled(CronetUrlRequest.this, mResponseInfo); 660 mCallback.onCanceled(CronetUrlRequest.this, mResponseInfo);
661 maybeReportMetrics();
666 } catch (Exception e) { 662 } catch (Exception e) {
667 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance led method", e); 663 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance led method", e);
668 } 664 }
669 } 665 }
670 }; 666 };
671 postTaskToExecutor(task); 667 postTaskToExecutor(task);
672 } 668 }
673 669
674 /** 670 /**
675 * Called by the native code when request status is fetched from the 671 * Called by the native code when request status is fetched from the
676 * native stack. 672 * native stack.
677 */ 673 */
678 @SuppressWarnings("unused") 674 @SuppressWarnings("unused")
679 @CalledByNative 675 @CalledByNative
680 private void onStatus( 676 private void onStatus(
681 final VersionSafeCallbacks.UrlRequestStatusListener listener, final int loadState) { 677 final VersionSafeCallbacks.UrlRequestStatusListener listener, final int loadState) {
682 Runnable task = new Runnable() { 678 Runnable task = new Runnable() {
683 @Override 679 @Override
684 public void run() { 680 public void run() {
685 listener.onStatus(convertLoadState(loadState)); 681 listener.onStatus(convertLoadState(loadState));
686 } 682 }
687 }; 683 };
688 postTaskToExecutor(task); 684 postTaskToExecutor(task);
689 } 685 }
690 686
691 /** 687 /**
692 * Called by the native code to report metrics. 688 * Called by the native code on the network thread to report metrics. Happen s before
689 * onSucceeded, onError and onCanceled.
693 */ 690 */
694 @SuppressWarnings("unused") 691 @SuppressWarnings("unused")
695 @CalledByNative 692 @CalledByNative
696 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d nsEndMs, 693 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d nsEndMs,
697 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd Ms, 694 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd Ms,
698 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE ndMs, 695 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE ndMs,
699 long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount, 696 long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount,
700 long receivedByteCount) { 697 long receivedByteCount) {
701 synchronized (mUrlRequestAdapterLock) { 698 synchronized (mUrlRequestAdapterLock) {
702 if (mMetrics != null) { 699 if (mMetrics != null) {
703 throw new IllegalStateException("Metrics collection should only happen once."); 700 throw new IllegalStateException("Metrics collection should only happen once.");
704 } 701 }
705 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c onnectStartMs, 702 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c onnectStartMs,
706 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE ndMs, pushStartMs, 703 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE ndMs, pushStartMs,
707 pushEndMs, responseStartMs, requestEndMs, socketReused, sent ByteCount, 704 pushEndMs, responseStartMs, requestEndMs, socketReused, sent ByteCount,
708 receivedByteCount); 705 receivedByteCount);
709 } 706 }
710 mRequestContext.reportFinished(getRequestFinishedInfo()); 707 // Metrics are reported to RequestFinishedListener when the final UrlReq uest.Callback has
708 // been invoked.
711 } 709 }
712 710
713 private RequestFinishedInfo getRequestFinishedInfo() { 711 /**
714 return new RequestFinishedInfoImpl(mInitialUrl, mRequestAnnotations, mMe trics, 712 * Called when the native adapter is destroyed.
715 mFinishedReason, mResponseInfo, mException); 713 */
714 @SuppressWarnings("unused")
715 @CalledByNative
716 private void onNativeAdapterDestroyed() {
717 synchronized (mUrlRequestAdapterLock) {
718 if (mOnDestroyedCallbackForTesting != null) {
719 mOnDestroyedCallbackForTesting.run();
720 }
721 // mException is set when an error is encountered (in native code vi a onError or in
722 // Java code). If mException is not null, notify the mCallback and r eport metrics.
723 if (mException == null) {
724 return;
725 }
726 }
727 Runnable task = new Runnable() {
728 @Override
729 public void run() {
730 try {
731 mCallback.onFailed(CronetUrlRequest.this, mResponseInfo, mEx ception);
732 maybeReportMetrics();
733 } catch (Exception e) {
734 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onFaile d method", e);
735 }
736 }
737 };
738 try {
739 mExecutor.execute(task);
740 } catch (RejectedExecutionException e) {
741 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", e);
742 }
716 } 743 }
717 744
718 /** Enforces prohibition of direct execution. */ 745 /** Enforces prohibition of direct execution. */
719 void checkCallingThread() { 746 void checkCallingThread() {
720 if (!mAllowDirectExecutor && mRequestContext.isNetworkThread(Thread.curr entThread())) { 747 if (!mAllowDirectExecutor && mRequestContext.isNetworkThread(Thread.curr entThread())) {
721 throw new InlineExecutionProhibitedException(); 748 throw new InlineExecutionProhibitedException();
722 } 749 }
723 } 750 }
724 751
725 private int mapUrlRequestErrorToApiErrorCode(int errorCode) { 752 private int mapUrlRequestErrorToApiErrorCode(int errorCode) {
(...skipping 19 matching lines...) Expand all
745 case UrlRequestError.QUIC_PROTOCOL_FAILED: 772 case UrlRequestError.QUIC_PROTOCOL_FAILED:
746 return NetworkException.ERROR_QUIC_PROTOCOL_FAILED; 773 return NetworkException.ERROR_QUIC_PROTOCOL_FAILED;
747 case UrlRequestError.OTHER: 774 case UrlRequestError.OTHER:
748 return NetworkException.ERROR_OTHER; 775 return NetworkException.ERROR_OTHER;
749 default: 776 default:
750 Log.e(CronetUrlRequestContext.LOG_TAG, "Unknown error code: " + errorCode); 777 Log.e(CronetUrlRequestContext.LOG_TAG, "Unknown error code: " + errorCode);
751 return errorCode; 778 return errorCode;
752 } 779 }
753 } 780 }
754 781
782 // Maybe report metrics. This method should only be called on Callback's exe cutor thread and
783 // after Callback's onSucceeded, onFailed and onCanceled.
784 private void maybeReportMetrics() {
785 if (mMetrics != null) {
786 mRequestContext.reportFinished(new RequestFinishedInfoImpl(mInitialU rl,
787 mRequestAnnotations, mMetrics, mFinishedReason, mResponseInf o, mException));
788 }
789 }
790
755 // Native methods are implemented in cronet_url_request_adapter.cc. 791 // Native methods are implemented in cronet_url_request_adapter.cc.
756 792
757 private native long nativeCreateRequestAdapter(long urlRequestContextAdapter , String url, 793 private native long nativeCreateRequestAdapter(long urlRequestContextAdapter , String url,
758 int priority, boolean disableCache, boolean disableConnectionMigrati on, 794 int priority, boolean disableCache, boolean disableConnectionMigrati on,
759 boolean enableMetrics); 795 boolean enableMetrics);
760 796
761 @NativeClassQualifiedName("CronetURLRequestAdapter") 797 @NativeClassQualifiedName("CronetURLRequestAdapter")
762 private native boolean nativeSetHttpMethod(long nativePtr, String method); 798 private native boolean nativeSetHttpMethod(long nativePtr, String method);
763 799
764 @NativeClassQualifiedName("CronetURLRequestAdapter") 800 @NativeClassQualifiedName("CronetURLRequestAdapter")
765 private native boolean nativeAddRequestHeader(long nativePtr, String name, S tring value); 801 private native boolean nativeAddRequestHeader(long nativePtr, String name, S tring value);
766 802
767 @NativeClassQualifiedName("CronetURLRequestAdapter") 803 @NativeClassQualifiedName("CronetURLRequestAdapter")
768 private native void nativeStart(long nativePtr); 804 private native void nativeStart(long nativePtr);
769 805
770 @NativeClassQualifiedName("CronetURLRequestAdapter") 806 @NativeClassQualifiedName("CronetURLRequestAdapter")
771 private native void nativeFollowDeferredRedirect(long nativePtr); 807 private native void nativeFollowDeferredRedirect(long nativePtr);
772 808
773 @NativeClassQualifiedName("CronetURLRequestAdapter") 809 @NativeClassQualifiedName("CronetURLRequestAdapter")
774 private native boolean nativeReadData( 810 private native boolean nativeReadData(
775 long nativePtr, ByteBuffer byteBuffer, int position, int capacity); 811 long nativePtr, ByteBuffer byteBuffer, int position, int capacity);
776 812
777 @NativeClassQualifiedName("CronetURLRequestAdapter") 813 @NativeClassQualifiedName("CronetURLRequestAdapter")
778 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled); 814 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled);
779 815
780 @NativeClassQualifiedName("CronetURLRequestAdapter") 816 @NativeClassQualifiedName("CronetURLRequestAdapter")
781 private native void nativeGetStatus( 817 private native void nativeGetStatus(
782 long nativePtr, VersionSafeCallbacks.UrlRequestStatusListener listen er); 818 long nativePtr, VersionSafeCallbacks.UrlRequestStatusListener listen er);
783 } 819 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698