Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |