| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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.JNINamespace; | 10 import org.chromium.base.annotations.JNINamespace; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 private final CronetUrlRequestContext mRequestContext; | 80 private final CronetUrlRequestContext mRequestContext; |
| 81 private final Executor mExecutor; | 81 private final Executor mExecutor; |
| 82 private final Callback mCallback; | 82 private final Callback mCallback; |
| 83 private final String mInitialUrl; | 83 private final String mInitialUrl; |
| 84 private final int mInitialPriority; | 84 private final int mInitialPriority; |
| 85 private final String mInitialMethod; | 85 private final String mInitialMethod; |
| 86 private final String mRequestHeaders[]; | 86 private final String mRequestHeaders[]; |
| 87 private final boolean mDelayRequestHeadersUntilFirstFlush; | 87 private final boolean mDelayRequestHeadersUntilFirstFlush; |
| 88 private final Collection<Object> mRequestAnnotations; | 88 private final Collection<Object> mRequestAnnotations; |
| 89 |
| 89 /* | 90 /* |
| 90 * Synchronizes access to mNativeStream, mReadState and mWriteState. | 91 * Synchronizes access to mNativeStream, mReadState and mWriteState. |
| 91 */ | 92 */ |
| 92 private final Object mNativeStreamLock = new Object(); | 93 private final Object mNativeStreamLock = new Object(); |
| 93 | 94 |
| 94 @GuardedBy("mNativeStreamLock") | 95 @GuardedBy("mNativeStreamLock") |
| 95 // Pending write data. | 96 // Pending write data. |
| 96 private LinkedList<ByteBuffer> mPendingData; | 97 private LinkedList<ByteBuffer> mPendingData; |
| 97 | 98 |
| 98 @GuardedBy("mNativeStreamLock") | 99 @GuardedBy("mNativeStreamLock") |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 241 |
| 241 @Override | 242 @Override |
| 242 public void start() { | 243 public void start() { |
| 243 synchronized (mNativeStreamLock) { | 244 synchronized (mNativeStreamLock) { |
| 244 if (mReadState != State.NOT_STARTED) { | 245 if (mReadState != State.NOT_STARTED) { |
| 245 throw new IllegalStateException("Stream is already started."); | 246 throw new IllegalStateException("Stream is already started."); |
| 246 } | 247 } |
| 247 try { | 248 try { |
| 248 mNativeStream = nativeCreateBidirectionalStream( | 249 mNativeStream = nativeCreateBidirectionalStream( |
| 249 mRequestContext.getUrlRequestContextAdapter(), | 250 mRequestContext.getUrlRequestContextAdapter(), |
| 250 !mDelayRequestHeadersUntilFirstFlush); | 251 !mDelayRequestHeadersUntilFirstFlush, |
| 252 mRequestContext.hasRequestFinishedListener()); |
| 251 mRequestContext.onRequestStarted(); | 253 mRequestContext.onRequestStarted(); |
| 252 // Non-zero startResult means an argument error. | 254 // Non-zero startResult means an argument error. |
| 253 int startResult = nativeStart(mNativeStream, mInitialUrl, mIniti
alPriority, | 255 int startResult = nativeStart(mNativeStream, mInitialUrl, mIniti
alPriority, |
| 254 mInitialMethod, mRequestHeaders, !doesMethodAllowWriteDa
ta(mInitialMethod)); | 256 mInitialMethod, mRequestHeaders, !doesMethodAllowWriteDa
ta(mInitialMethod)); |
| 255 if (startResult == -1) { | 257 if (startResult == -1) { |
| 256 throw new IllegalArgumentException("Invalid http method " +
mInitialMethod); | 258 throw new IllegalArgumentException("Invalid http method " +
mInitialMethod); |
| 257 } | 259 } |
| 258 if (startResult > 0) { | 260 if (startResult > 0) { |
| 259 int headerPos = startResult - 1; | 261 int headerPos = startResult - 1; |
| 260 throw new IllegalArgumentException("Invalid header " | 262 throw new IllegalArgumentException("Invalid header " |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 public void run() { | 614 public void run() { |
| 613 try { | 615 try { |
| 614 mCallback.onCanceled(CronetBidirectionalStream.this, mRespon
seInfo); | 616 mCallback.onCanceled(CronetBidirectionalStream.this, mRespon
seInfo); |
| 615 } catch (Exception e) { | 617 } catch (Exception e) { |
| 616 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance
led method", e); | 618 Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in onCance
led method", e); |
| 617 } | 619 } |
| 618 } | 620 } |
| 619 }); | 621 }); |
| 620 } | 622 } |
| 621 | 623 |
| 624 /** |
| 625 * Called by the native code to report metrics just before the native adapter
is destroyed. |
| 626 */ |
| 627 @SuppressWarnings("unused") |
| 628 @CalledByNative |
| 629 private void onMetricsCollected(long requestStartMs, long dnsStartMs, long d
nsEndMs, |
| 630 long connectStartMs, long connectEndMs, long sslStartMs, long sslEnd
Ms, |
| 631 long sendingStartMs, long sendingEndMs, long pushStartMs, long pushE
ndMs, |
| 632 long responseStartMs, long responseEndMs, boolean socketReused, long
sentBytesCount, |
| 633 long receivedBytesCount) { |
| 634 synchronized (mNativeStreamLock) { |
| 635 if (mMetrics != null) { |
| 636 throw new IllegalStateException("Metrics collection should only
happen once."); |
| 637 } |
| 638 mMetrics = new CronetMetrics(requestStartMs, dnsStartMs, dnsEndMs, c
onnectStartMs, |
| 639 connectEndMs, sslStartMs, sslEndMs, sendingStartMs, sendingE
ndMs, pushStartMs, |
| 640 pushEndMs, responseStartMs, responseEndMs, socketReused, sen
tBytesCount, |
| 641 receivedBytesCount); |
| 642 // TODO(xunjieli): Fill this with real values. |
| 643 final RequestFinishedInfo requestFinishedInfo = |
| 644 new RequestFinishedInfo(mInitialUrl, mRequestAnnotations, mM
etrics, |
| 645 RequestFinishedInfo.SUCCEEDED, mResponseInfo, null); |
| 646 mRequestContext.reportFinished(requestFinishedInfo); |
| 647 } |
| 648 } |
| 649 |
| 622 @VisibleForTesting | 650 @VisibleForTesting |
| 623 public void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackFor
Testing) { | 651 public void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackFor
Testing) { |
| 624 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; | 652 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; |
| 625 } | 653 } |
| 626 | 654 |
| 627 private static boolean doesMethodAllowWriteData(String methodName) { | 655 private static boolean doesMethodAllowWriteData(String methodName) { |
| 628 return !methodName.equals("GET") && !methodName.equals("HEAD"); | 656 return !methodName.equals("GET") && !methodName.equals("HEAD"); |
| 629 } | 657 } |
| 630 | 658 |
| 631 private static ArrayList<Map.Entry<String, String>> headersListFromStrings(S
tring[] headers) { | 659 private static ArrayList<Map.Entry<String, String>> headersListFromStrings(S
tring[] headers) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 return responseInfo; | 720 return responseInfo; |
| 693 } | 721 } |
| 694 | 722 |
| 695 @GuardedBy("mNativeStreamLock") | 723 @GuardedBy("mNativeStreamLock") |
| 696 private void destroyNativeStreamLocked(boolean sendOnCanceled) { | 724 private void destroyNativeStreamLocked(boolean sendOnCanceled) { |
| 697 Log.i(CronetUrlRequestContext.LOG_TAG, "destroyNativeStreamLocked " + th
is.toString()); | 725 Log.i(CronetUrlRequestContext.LOG_TAG, "destroyNativeStreamLocked " + th
is.toString()); |
| 698 if (mNativeStream == 0) { | 726 if (mNativeStream == 0) { |
| 699 return; | 727 return; |
| 700 } | 728 } |
| 701 nativeDestroy(mNativeStream, sendOnCanceled); | 729 nativeDestroy(mNativeStream, sendOnCanceled); |
| 702 mRequestContext.reportFinished(getRequestFinishedInfo()); | |
| 703 mRequestContext.onRequestDestroyed(); | 730 mRequestContext.onRequestDestroyed(); |
| 704 mNativeStream = 0; | 731 mNativeStream = 0; |
| 705 if (mOnDestroyedCallbackForTesting != null) { | 732 if (mOnDestroyedCallbackForTesting != null) { |
| 706 mOnDestroyedCallbackForTesting.run(); | 733 mOnDestroyedCallbackForTesting.run(); |
| 707 } | 734 } |
| 708 } | 735 } |
| 709 | 736 |
| 710 private RequestFinishedInfo getRequestFinishedInfo() { | |
| 711 // TODO(xunjieli): Fill this with real values. | |
| 712 return new RequestFinishedInfo(mInitialUrl, mRequestAnnotations, mMetric
s, | |
| 713 RequestFinishedInfo.SUCCEEDED, mResponseInfo, null); | |
| 714 } | |
| 715 | |
| 716 /** | 737 /** |
| 717 * Fails the stream with an exception. Only called on the Executor. | 738 * Fails the stream with an exception. Only called on the Executor. |
| 718 */ | 739 */ |
| 719 private void failWithExceptionOnExecutor(CronetException e) { | 740 private void failWithExceptionOnExecutor(CronetException e) { |
| 720 // Do not call into mCallback if request is complete. | 741 // Do not call into mCallback if request is complete. |
| 721 synchronized (mNativeStreamLock) { | 742 synchronized (mNativeStreamLock) { |
| 722 if (isDoneLocked()) { | 743 if (isDoneLocked()) { |
| 723 return; | 744 return; |
| 724 } | 745 } |
| 725 mReadState = mWriteState = State.ERROR; | 746 mReadState = mWriteState = State.ERROR; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 750 */ | 771 */ |
| 751 private void failWithException(final CronetException exception) { | 772 private void failWithException(final CronetException exception) { |
| 752 postTaskToExecutor(new Runnable() { | 773 postTaskToExecutor(new Runnable() { |
| 753 public void run() { | 774 public void run() { |
| 754 failWithExceptionOnExecutor(exception); | 775 failWithExceptionOnExecutor(exception); |
| 755 } | 776 } |
| 756 }); | 777 }); |
| 757 } | 778 } |
| 758 | 779 |
| 759 // Native methods are implemented in cronet_bidirectional_stream_adapter.cc. | 780 // Native methods are implemented in cronet_bidirectional_stream_adapter.cc. |
| 760 private native long nativeCreateBidirectionalStream( | 781 private native long nativeCreateBidirectionalStream(long urlRequestContextAd
apter, |
| 761 long urlRequestContextAdapter, boolean sendRequestHeadersAutomatical
ly); | 782 boolean sendRequestHeadersAutomatically, boolean enableMetricsCollec
tion); |
| 762 | 783 |
| 763 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") | 784 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") |
| 764 private native int nativeStart(long nativePtr, String url, int priority, Str
ing method, | 785 private native int nativeStart(long nativePtr, String url, int priority, Str
ing method, |
| 765 String[] headers, boolean endOfStream); | 786 String[] headers, boolean endOfStream); |
| 766 | 787 |
| 767 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") | 788 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") |
| 768 private native void nativeSendRequestHeaders(long nativePtr); | 789 private native void nativeSendRequestHeaders(long nativePtr); |
| 769 | 790 |
| 770 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") | 791 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") |
| 771 private native boolean nativeReadData( | 792 private native boolean nativeReadData( |
| 772 long nativePtr, ByteBuffer byteBuffer, int position, int limit); | 793 long nativePtr, ByteBuffer byteBuffer, int position, int limit); |
| 773 | 794 |
| 774 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") | 795 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") |
| 775 private native boolean nativeWritevData(long nativePtr, ByteBuffer[] buffers
, int[] positions, | 796 private native boolean nativeWritevData(long nativePtr, ByteBuffer[] buffers
, int[] positions, |
| 776 int[] limits, boolean endOfStream); | 797 int[] limits, boolean endOfStream); |
| 777 | 798 |
| 778 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") | 799 @NativeClassQualifiedName("CronetBidirectionalStreamAdapter") |
| 779 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled); | 800 private native void nativeDestroy(long nativePtr, boolean sendOnCanceled); |
| 780 } | 801 } |
| OLD | NEW |