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 |