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