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 |