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

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.
90 // They are read on executor's thread after the last update.
mef 2017/04/28 21:16:54 Should they be @GuardedBy("mUrlRequestAdapterLock"
mgersh 2017/05/01 15:29:22 this could clarify which executor
xunjieli 2017/05/01 19:17:16 Done.
xunjieli 2017/05/01 19:17:16 These three are not guarded by the lock because th
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. Use
238 // exception to the caller. 241 // null to avoid rethrowing in onDestroy().
239 destroyRequestAdapter(false); 242 synchronized (mUrlRequestAdapterLock) {
mef 2017/04/28 21:16:54 This whole method is synchronized() at line 191, s
xunjieli 2017/05/01 19:17:16 Done.
243 setIsDoneLocked(null, RequestFinishedInfo.FAILED);
244 }
240 throw e; 245 throw e;
241 } 246 }
242 mStarted = true; 247 mStarted = true;
243 startInternalLocked(); 248 startInternalLocked();
244 } 249 }
245 } 250 }
246 251
247 /* 252 /*
248 * Starts fully configured request. Could execute on UploadDataProvider exec utor. 253 * 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. 254 * 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 } 296 }
292 } 297 }
293 } 298 }
294 299
295 @Override 300 @Override
296 public void cancel() { 301 public void cancel() {
297 synchronized (mUrlRequestAdapterLock) { 302 synchronized (mUrlRequestAdapterLock) {
298 if (isDoneLocked() || !mStarted) { 303 if (isDoneLocked() || !mStarted) {
299 return; 304 return;
300 } 305 }
301 destroyRequestAdapter(true); 306 setIsDoneLocked(null, RequestFinishedInfo.CANCELED);
302 } 307 }
303 } 308 }
304 309
305 @Override 310 @Override
306 public boolean isDone() { 311 public boolean isDone() {
307 synchronized (mUrlRequestAdapterLock) { 312 synchronized (mUrlRequestAdapterLock) {
308 return isDoneLocked(); 313 return isDoneLocked();
309 } 314 }
310 } 315 }
311 316
317 /**
318 * Helper method to set final status of CronetUrlRequest and clean up the
319 * native request adapter.
320 */
321 @GuardedBy("mUrlRequestAdapterLock")
322 private void setIsDoneLocked(
mef 2017/04/28 21:16:55 I really think it should still be called destroyRe
xunjieli 2017/05/01 19:17:16 Done. Partly yes, but now it also updates |mExcept
323 CronetException exception, @RequestFinishedInfoImpl.FinishedReason i nt finishedReason) {
324 assert mException == null;
325 assert exception == null || finishedReason == RequestFinishedInfo.FAILED ;
326 mException = exception;
327 mFinishedReason = finishedReason;
328 if (mUrlRequestAdapter == 0) {
329 return;
330 }
331 mRequestContext.onRequestDestroyed();
332 // Posts a task to destroy the native adapter.
333 nativeDestroy(mUrlRequestAdapter, finishedReason == RequestFinishedInfo. CANCELED);
334 mUrlRequestAdapter = 0;
335 }
336
312 @GuardedBy("mUrlRequestAdapterLock") 337 @GuardedBy("mUrlRequestAdapterLock")
313 private boolean isDoneLocked() { 338 private boolean isDoneLocked() {
314 return mStarted && mUrlRequestAdapter == 0; 339 return mStarted && mUrlRequestAdapter == 0;
315 } 340 }
316 341
317 @Override 342 @Override
318 public void getStatus(UrlRequest.StatusListener unsafeListener) { 343 public void getStatus(UrlRequest.StatusListener unsafeListener) {
319 final VersionSafeCallbacks.UrlRequestStatusListener listener = 344 final VersionSafeCallbacks.UrlRequestStatusListener listener =
320 new VersionSafeCallbacks.UrlRequestStatusListener(unsafeListener ); 345 new VersionSafeCallbacks.UrlRequestStatusListener(unsafeListener );
321 synchronized (mUrlRequestAdapterLock) { 346 synchronized (mUrlRequestAdapterLock) {
322 if (mUrlRequestAdapter != 0) { 347 if (mUrlRequestAdapter != 0) {
323 nativeGetStatus(mUrlRequestAdapter, listener); 348 nativeGetStatus(mUrlRequestAdapter, listener);
324 return; 349 return;
325 } 350 }
326 } 351 }
327 Runnable task = new Runnable() { 352 Runnable task = new Runnable() {
328 @Override 353 @Override
329 public void run() { 354 public void run() {
330 listener.onStatus(UrlRequest.Status.INVALID); 355 listener.onStatus(UrlRequest.Status.INVALID);
331 } 356 }
332 }; 357 };
333 postTaskToExecutor(task); 358 postTaskToExecutor(task);
334 } 359 }
335 360
336 @VisibleForTesting 361 @VisibleForTesting
337 public void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackFor Testing) { 362 public void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackFor Testing) {
338 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; 363 synchronized (mUrlRequestAdapterLock) {
364 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting;
365 }
339 } 366 }
340 367
341 @VisibleForTesting 368 @VisibleForTesting
342 public void setOnDestroyedUploadCallbackForTesting( 369 public void setOnDestroyedUploadCallbackForTesting(
343 Runnable onDestroyedUploadCallbackForTesting) { 370 Runnable onDestroyedUploadCallbackForTesting) {
344 mUploadDataStream.setOnDestroyedCallbackForTesting(onDestroyedUploadCall backForTesting); 371 mUploadDataStream.setOnDestroyedCallbackForTesting(onDestroyedUploadCall backForTesting);
345 } 372 }
346 373
347 @VisibleForTesting 374 @VisibleForTesting
348 public long getUrlRequestAdapterForTesting() { 375 public long getUrlRequestAdapterForTesting() {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 430 }
404 431
405 private void checkNotStarted() { 432 private void checkNotStarted() {
406 synchronized (mUrlRequestAdapterLock) { 433 synchronized (mUrlRequestAdapterLock) {
407 if (mStarted || isDoneLocked()) { 434 if (mStarted || isDoneLocked()) {
408 throw new IllegalStateException("Request is already started."); 435 throw new IllegalStateException("Request is already started.");
409 } 436 }
410 } 437 }
411 } 438 }
412 439
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 /** 440 /**
428 * If callback method throws an exception, request gets canceled 441 * If callback method throws an exception, request gets canceled
429 * and exception is reported via onFailed listener callback. 442 * and exception is reported via onFailed listener callback.
430 * Only called on the Executor. 443 * Only called on the Executor.
431 */ 444 */
432 private void onCallbackException(Exception e) { 445 private void onCallbackException(Exception e) {
433 CallbackException requestError = 446 CallbackException requestError =
434 new CallbackExceptionImpl("Exception received from UrlRequest.Ca llback", e); 447 new CallbackExceptionImpl("Exception received from UrlRequest.Ca llback", e);
435 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in CalledByNative meth od", e); 448 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in CalledByNative meth od", e);
436 failWithException(requestError); 449 failWithException(requestError);
437 } 450 }
438 451
439 /** 452 /**
440 * Called when UploadDataProvider encounters an error. 453 * Called when UploadDataProvider encounters an error.
441 */ 454 */
442 void onUploadException(Throwable e) { 455 void onUploadException(Throwable e) {
443 CallbackException uploadError = 456 CallbackException uploadError =
444 new CallbackExceptionImpl("Exception received from UploadDataPro vider", e); 457 new CallbackExceptionImpl("Exception received from UploadDataPro vider", e);
445 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in upload method", e); 458 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in upload method", e);
446 failWithException(uploadError); 459 failWithException(uploadError);
447 } 460 }
448 461
449 /** 462 /**
450 * Fails the request with an exception. Can be called on any thread. 463 * Fails the request with an exception on any thread.
451 */ 464 */
452 private void failWithException(final CronetException exception) { 465 private void failWithException(final CronetException exception) {
453 mException = exception;
454 synchronized (mUrlRequestAdapterLock) { 466 synchronized (mUrlRequestAdapterLock) {
455 if (isDoneLocked()) { 467 if (isDoneLocked()) {
456 return; 468 return;
457 } 469 }
458 destroyRequestAdapter(false); 470 setIsDoneLocked(exception, RequestFinishedInfo.FAILED);
mef 2017/04/28 21:16:54 Can we set mException = exception; here and just p
xunjieli 2017/05/01 19:17:16 Done.
459 } 471 }
460 Runnable task = new Runnable() { 472 // Wait until onDestroy() is called to propagate the error to caller to
mef 2017/04/28 21:16:54 I would rephrase this like 'The onFailed callback
xunjieli 2017/05/01 19:17:16 Done.
461 @Override 473 // gather metrics.
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 } 474 }
476 475
477 //////////////////////////////////////////////// 476 ////////////////////////////////////////////////
478 // Private methods called by the native code. 477 // Private methods called by the native code.
479 // Always called on network thread. 478 // Always called on network thread.
480 //////////////////////////////////////////////// 479 ////////////////////////////////////////////////
481 480
482 /** 481 /**
483 * Called before following redirects. The redirect will only be followed if 482 * 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. 483 * {@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 592
594 /** 593 /**
595 * Called when request is completed successfully, no callbacks will be 594 * Called when request is completed successfully, no callbacks will be
596 * called afterwards. 595 * called afterwards.
597 * 596 *
598 * @param receivedByteCount number of bytes received. 597 * @param receivedByteCount number of bytes received.
599 */ 598 */
600 @SuppressWarnings("unused") 599 @SuppressWarnings("unused")
601 @CalledByNative 600 @CalledByNative
602 private void onSucceeded(long receivedByteCount) { 601 private void onSucceeded(long receivedByteCount) {
603 mFinishedReason = RequestFinishedInfo.SUCCEEDED;
604 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + rec eivedByteCount); 602 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + rec eivedByteCount);
605 Runnable task = new Runnable() { 603 Runnable task = new Runnable() {
606 @Override 604 @Override
607 public void run() { 605 public void run() {
608 synchronized (mUrlRequestAdapterLock) { 606 synchronized (mUrlRequestAdapterLock) {
609 if (isDoneLocked()) { 607 if (isDoneLocked()) {
610 return; 608 return;
611 } 609 }
612 // Destroy adapter first, so request context could be shut 610 // Destroy adapter first, so request context could be shut
613 // down from the listener. 611 // down from the listener.
614 destroyRequestAdapter(false); 612 setIsDoneLocked(null, RequestFinishedInfo.SUCCEEDED);
615 } 613 }
616 try { 614 try {
617 mCallback.onSucceeded(CronetUrlRequest.this, mResponseInfo); 615 mCallback.onSucceeded(CronetUrlRequest.this, mResponseInfo);
616 if (mMetrics != null) {
617 mRequestContext.reportFinished(
618 new RequestFinishedInfoImpl(mInitialUrl, mReques tAnnotations,
619 mMetrics, mFinishedReason, mResponseInfo , mException));
620 }
618 } catch (Exception e) { 621 } catch (Exception e) {
619 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCompl ete method", e); 622 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onSucce eded method", e);
620 } 623 }
621 } 624 }
622 }; 625 };
623 postTaskToExecutor(task); 626 postTaskToExecutor(task);
624 } 627 }
625 628
626 /** 629 /**
627 * Called when error has occured, no callbacks will be called afterwards. 630 * Called when error has occured, no callbacks will be called afterwards.
628 * 631 *
629 * @param errorCode Error code represented by {@code UrlRequestError} that s hould be mapped 632 * @param errorCode Error code represented by {@code UrlRequestError} that s hould be mapped
630 * to one of {@link NetworkException#ERROR_HOSTNAME_NOT_RES OLVED 633 * to one of {@link NetworkException#ERROR_HOSTNAME_NOT_RES OLVED
631 * NetworkException.ERROR_*}. 634 * NetworkException.ERROR_*}.
632 * @param nativeError native net error code. 635 * @param nativeError native net error code.
633 * @param errorString textual representation of the error code. 636 * @param errorString textual representation of the error code.
634 * @param receivedByteCount number of bytes received. 637 * @param receivedByteCount number of bytes received.
635 */ 638 */
636 @SuppressWarnings("unused") 639 @SuppressWarnings("unused")
637 @CalledByNative 640 @CalledByNative
638 private void onError(int errorCode, int nativeError, int nativeQuicError, St ring errorString, 641 private void onError(int errorCode, int nativeError, int nativeQuicError, St ring errorString,
639 long receivedByteCount) { 642 long receivedByteCount) {
640 mFinishedReason = RequestFinishedInfo.FAILED;
641 if (mResponseInfo != null) { 643 if (mResponseInfo != null) {
642 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + receivedByteCount); 644 mResponseInfo.setReceivedByteCount(mReceivedByteCountFromRedirects + receivedByteCount);
643 } 645 }
646 CronetException exception;
mef 2017/04/28 21:16:54 Why do we need local |exception| here?
xunjieli 2017/05/01 19:17:16 Done. Because we can acquire mUrlRequestAdapterLoc
644 if (errorCode == NetworkException.ERROR_QUIC_PROTOCOL_FAILED) { 647 if (errorCode == NetworkException.ERROR_QUIC_PROTOCOL_FAILED) {
645 failWithException(new QuicExceptionImpl( 648 exception = new QuicExceptionImpl(
646 "Exception in CronetUrlRequest: " + errorString, nativeError , nativeQuicError)); 649 "Exception in CronetUrlRequest: " + errorString, nativeError , nativeQuicError);
647 } else { 650 } else {
648 int javaError = mapUrlRequestErrorToApiErrorCode(errorCode); 651 int javaError = mapUrlRequestErrorToApiErrorCode(errorCode);
649 failWithException(new NetworkExceptionImpl( 652 exception = new NetworkExceptionImpl(
650 "Exception in CronetUrlRequest: " + errorString, javaError, nativeError)); 653 "Exception in CronetUrlRequest: " + errorString, javaError, nativeError);
651 } 654 }
655 failWithException(exception);
652 } 656 }
653 657
654 /** 658 /**
655 * Called when request is canceled, no callbacks will be called afterwards. 659 * Called when request is canceled, no callbacks will be called afterwards.
656 */ 660 */
657 @SuppressWarnings("unused") 661 @SuppressWarnings("unused")
658 @CalledByNative 662 @CalledByNative
659 private void onCanceled() { 663 private void onCanceled() {
660 mFinishedReason = RequestFinishedInfo.CANCELED;
661 Runnable task = new Runnable() { 664 Runnable task = new Runnable() {
662 @Override 665 @Override
663 public void run() { 666 public void run() {
664 try { 667 try {
665 mCallback.onCanceled(CronetUrlRequest.this, mResponseInfo); 668 mCallback.onCanceled(CronetUrlRequest.this, mResponseInfo);
669 if (mMetrics != null) {
mef 2017/04/28 21:16:54 Does it make sense to extract this into maybeRepor
xunjieli 2017/05/01 19:17:16 Done.
670 mRequestContext.reportFinished(
671 new RequestFinishedInfoImpl(mInitialUrl, mReques tAnnotations,
672 mMetrics, mFinishedReason, mResponseInfo , mException));
673 }
666 } catch (Exception e) { 674 } catch (Exception e) {
667 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance led method", e); 675 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance led method", e);
668 } 676 }
669 } 677 }
670 }; 678 };
671 postTaskToExecutor(task); 679 postTaskToExecutor(task);
672 } 680 }
673 681
674 /** 682 /**
675 * Called by the native code when request status is fetched from the 683 * Called by the native code when request status is fetched from the
676 * native stack. 684 * native stack.
677 */ 685 */
678 @SuppressWarnings("unused") 686 @SuppressWarnings("unused")
679 @CalledByNative 687 @CalledByNative
680 private void onStatus( 688 private void onStatus(
681 final VersionSafeCallbacks.UrlRequestStatusListener listener, final int loadState) { 689 final VersionSafeCallbacks.UrlRequestStatusListener listener, final int loadState) {
682 Runnable task = new Runnable() { 690 Runnable task = new Runnable() {
683 @Override 691 @Override
684 public void run() { 692 public void run() {
685 listener.onStatus(convertLoadState(loadState)); 693 listener.onStatus(convertLoadState(loadState));
686 } 694 }
687 }; 695 };
688 postTaskToExecutor(task); 696 postTaskToExecutor(task);
689 } 697 }
690 698
691 /** 699 /**
692 * Called by the native code to report metrics. 700 * Called by the native code on the network thread to report metrics. Happen s before
701 * onSucceeded, onError and onCanceled.
693 */ 702 */
694 @SuppressWarnings("unused") 703 @SuppressWarnings("unused")
695 @CalledByNative 704 @CalledByNative
696 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d nsEndMs, 705 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d nsEndMs,
697 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd Ms, 706 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd Ms,
698 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE ndMs, 707 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE ndMs,
699 long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount, 708 long responseStartMs, long requestEndMs, boolean socketReused, long sentByteCount,
700 long receivedByteCount) { 709 long receivedByteCount) {
701 synchronized (mUrlRequestAdapterLock) { 710 synchronized (mUrlRequestAdapterLock) {
702 if (mMetrics != null) { 711 if (mMetrics != null) {
703 throw new IllegalStateException("Metrics collection should only happen once."); 712 throw new IllegalStateException("Metrics collection should only happen once.");
704 } 713 }
705 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c onnectStartMs, 714 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c onnectStartMs,
706 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE ndMs, pushStartMs, 715 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE ndMs, pushStartMs,
707 pushEndMs, responseStartMs, requestEndMs, socketReused, sent ByteCount, 716 pushEndMs, responseStartMs, requestEndMs, socketReused, sent ByteCount,
708 receivedByteCount); 717 receivedByteCount);
709 } 718 }
mef 2017/04/28 21:16:54 Maybe add comment that metrics will be reported af
xunjieli 2017/05/01 19:17:16 Done.
710 mRequestContext.reportFinished(getRequestFinishedInfo());
711 } 719 }
712 720
713 private RequestFinishedInfo getRequestFinishedInfo() { 721 /**
714 return new RequestFinishedInfoImpl(mInitialUrl, mRequestAnnotations, mMe trics, 722 * Called when the native adapter is destroyed.
715 mFinishedReason, mResponseInfo, mException); 723 */
724 @SuppressWarnings("unused")
725 @CalledByNative
726 private void onDestroyed() {
mef 2017/04/28 21:16:55 Maybe (not strongly) call it onNativeAdapterDestro
xunjieli 2017/05/01 19:17:16 Done.
727 synchronized (mUrlRequestAdapterLock) {
728 if (mOnDestroyedCallbackForTesting != null) {
729 mOnDestroyedCallbackForTesting.run();
730 }
731 if (mException == null) {
mef 2017/04/28 21:16:55 Need a comment as to why we check mException and
xunjieli 2017/05/01 19:17:16 Done.
732 return;
733 }
734 }
735 Runnable task = new Runnable() {
736 @Override
737 public void run() {
738 try {
739 mCallback.onFailed(CronetUrlRequest.this, mResponseInfo, mEx ception);
740 if (mMetrics != null) {
741 mRequestContext.reportFinished(
742 new RequestFinishedInfoImpl(mInitialUrl, mReques tAnnotations,
743 mMetrics, mFinishedReason, mResponseInfo , mException));
744 }
745 } catch (Exception e) {
746 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onFaile d method", e);
747 }
748 }
749 };
750 try {
751 mExecutor.execute(task);
752 } catch (RejectedExecutionException e) {
753 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception posting task to ex ecutor", e);
754 }
716 } 755 }
717 756
718 /** Enforces prohibition of direct execution. */ 757 /** Enforces prohibition of direct execution. */
719 void checkCallingThread() { 758 void checkCallingThread() {
720 if (!mAllowDirectExecutor && mRequestContext.isNetworkThread(Thread.curr entThread())) { 759 if (!mAllowDirectExecutor && mRequestContext.isNetworkThread(Thread.curr entThread())) {
721 throw new InlineExecutionProhibitedException(); 760 throw new InlineExecutionProhibitedException();
722 } 761 }
723 } 762 }
724 763
725 private int mapUrlRequestErrorToApiErrorCode(int errorCode) { 764 private int mapUrlRequestErrorToApiErrorCode(int errorCode) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 private native boolean nativeReadData( 813 private native boolean nativeReadData(
775 long nativePtr, ByteBuffer byteBuffer, int position, int capacity); 814 long nativePtr, ByteBuffer byteBuffer, int position, int capacity);
776 815
777 @NativeClassQualifiedName("CronetURLRequestAdapter") 816 @NativeClassQualifiedName("CronetURLRequestAdapter")
778 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled); 817 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled);
779 818
780 @NativeClassQualifiedName("CronetURLRequestAdapter") 819 @NativeClassQualifiedName("CronetURLRequestAdapter")
781 private native void nativeGetStatus( 820 private native void nativeGetStatus(
782 long nativePtr, VersionSafeCallbacks.UrlRequestStatusListener listen er); 821 long nativePtr, VersionSafeCallbacks.UrlRequestStatusListener listen er);
783 } 822 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698