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; | 5 package org.chromium.net.impl; |
6 | 6 |
7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
8 import android.annotation.TargetApi; | 8 import android.annotation.TargetApi; |
9 import android.net.TrafficStats; | 9 import android.net.TrafficStats; |
10 import android.os.Build; | 10 import android.os.Build; |
11 import android.util.Log; | 11 |
| 12 import org.chromium.base.Log; |
| 13 import org.chromium.net.InlineExecutionProhibitedException; |
| 14 import org.chromium.net.UploadDataProvider; |
| 15 import org.chromium.net.UploadDataSink; |
| 16 import org.chromium.net.UrlRequestException; |
| 17 import org.chromium.net.UrlResponseInfo; |
12 | 18 |
13 import java.io.Closeable; | 19 import java.io.Closeable; |
14 import java.io.IOException; | 20 import java.io.IOException; |
15 import java.io.OutputStream; | 21 import java.io.OutputStream; |
16 import java.net.HttpURLConnection; | 22 import java.net.HttpURLConnection; |
17 import java.net.URI; | 23 import java.net.URI; |
18 import java.net.URL; | 24 import java.net.URL; |
19 import java.nio.ByteBuffer; | 25 import java.nio.ByteBuffer; |
20 import java.nio.channels.Channels; | 26 import java.nio.channels.Channels; |
21 import java.nio.channels.ReadableByteChannel; | 27 import java.nio.channels.ReadableByteChannel; |
22 import java.nio.channels.WritableByteChannel; | 28 import java.nio.channels.WritableByteChannel; |
23 import java.util.AbstractMap.SimpleEntry; | 29 import java.util.AbstractMap.SimpleEntry; |
24 import java.util.ArrayList; | 30 import java.util.ArrayList; |
25 import java.util.Collections; | 31 import java.util.Collections; |
26 import java.util.List; | 32 import java.util.List; |
27 import java.util.Map; | 33 import java.util.Map; |
28 import java.util.TreeMap; | 34 import java.util.TreeMap; |
29 import java.util.concurrent.Executor; | 35 import java.util.concurrent.Executor; |
30 import java.util.concurrent.RejectedExecutionException; | 36 import java.util.concurrent.RejectedExecutionException; |
31 import java.util.concurrent.atomic.AtomicBoolean; | 37 import java.util.concurrent.atomic.AtomicBoolean; |
32 import java.util.concurrent.atomic.AtomicReference; | 38 import java.util.concurrent.atomic.AtomicReference; |
33 | 39 |
34 /** | 40 /** |
35 * Pure java UrlRequest, backed by {@link HttpURLConnection}. | 41 * Pure java UrlRequest, backed by {@link HttpURLConnection}. |
36 */ | 42 */ |
37 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) // TrafficStats only availabl
e on ICS | 43 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) // TrafficStats only availabl
e on ICS |
38 final class JavaUrlRequest implements UrlRequest { | 44 final class JavaUrlRequest extends UrlRequestBase { |
39 private static final String X_ANDROID = "X-Android"; | 45 private static final String X_ANDROID = "X-Android"; |
40 private static final String X_ANDROID_SELECTED_TRANSPORT = "X-Android-Select
ed-Transport"; | 46 private static final String X_ANDROID_SELECTED_TRANSPORT = "X-Android-Select
ed-Transport"; |
41 private static final String TAG = "JavaUrlConnection"; | 47 private static final String TAG = "JavaUrlConnection"; |
42 private static final int DEFAULT_UPLOAD_BUFFER_SIZE = 8192; | 48 private static final int DEFAULT_UPLOAD_BUFFER_SIZE = 8192; |
43 private static final int DEFAULT_CHUNK_LENGTH = DEFAULT_UPLOAD_BUFFER_SIZE; | 49 private static final int DEFAULT_CHUNK_LENGTH = DEFAULT_UPLOAD_BUFFER_SIZE; |
44 private static final String USER_AGENT = "User-Agent"; | 50 private static final String USER_AGENT = "User-Agent"; |
45 private final AsyncUrlRequestCallback mCallbackAsync; | 51 private final AsyncUrlRequestCallback mCallbackAsync; |
46 private final Executor mExecutor; | 52 private final Executor mExecutor; |
47 private final String mUserAgent; | 53 private final String mUserAgent; |
48 private final Map<String, String> mRequestHeaders = | 54 private final Map<String, String> mRequestHeaders = |
(...skipping 27 matching lines...) Expand all Loading... |
76 /** | 82 /** |
77 * Holds a subset of StatusValues - {@link State#STARTED} can represent | 83 * Holds a subset of StatusValues - {@link State#STARTED} can represent |
78 * {@link Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. Wh
ile the distinction | 84 * {@link Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. Wh
ile the distinction |
79 * isn't needed to implement the logic in this class, it is needed to implem
ent | 85 * isn't needed to implement the logic in this class, it is needed to implem
ent |
80 * {@link #getStatus(StatusListener)}. | 86 * {@link #getStatus(StatusListener)}. |
81 * | 87 * |
82 * <p>Concurrency notes - this value is not atomically updated with mState,
so there is some | 88 * <p>Concurrency notes - this value is not atomically updated with mState,
so there is some |
83 * risk that we'd get an inconsistent snapshot of both - however, it also ha
ppens that this | 89 * risk that we'd get an inconsistent snapshot of both - however, it also ha
ppens that this |
84 * value is only used with the STARTED state, so it's inconsequential. | 90 * value is only used with the STARTED state, so it's inconsequential. |
85 */ | 91 */ |
86 @Status.StatusValues private volatile int mAdditionalStatusDetails = Status.
INVALID; | 92 @StatusConverter.StatusValues |
| 93 private volatile int mAdditionalStatusDetails = Status.INVALID; |
87 | 94 |
88 /* These change with redirects. */ | 95 /* These change with redirects. */ |
89 private String mCurrentUrl; | 96 private String mCurrentUrl; |
90 private ReadableByteChannel mResponseChannel; | 97 private ReadableByteChannel mResponseChannel; |
91 private UrlResponseInfo mUrlResponseInfo; | 98 private UrlResponseInfo mUrlResponseInfo; |
92 private String mPendingRedirectUrl; | 99 private String mPendingRedirectUrl; |
93 /** | 100 /** |
94 * The happens-before edges created by the executor submission and AtomicRef
erence setting are | 101 * The happens-before edges created by the executor submission and AtomicRef
erence setting are |
95 * sufficient to guarantee the correct behavior of this field; however, this
is an | 102 * sufficient to guarantee the correct behavior of this field; however, this
is an |
96 * AtomicReference so that we can cleanly dispose of a new connection if we'
re cancelled during | 103 * AtomicReference so that we can cleanly dispose of a new connection if we'
re cancelled during |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 } | 256 } |
250 } | 257 } |
251 | 258 |
252 private enum SinkState { | 259 private enum SinkState { |
253 AWAITING_READ_RESULT, | 260 AWAITING_READ_RESULT, |
254 AWAITING_REWIND_RESULT, | 261 AWAITING_REWIND_RESULT, |
255 UPLOADING, | 262 UPLOADING, |
256 NOT_STARTED, | 263 NOT_STARTED, |
257 } | 264 } |
258 | 265 |
259 private final class OutputStreamDataSink implements UploadDataSink { | 266 private final class OutputStreamDataSink extends UploadDataSink { |
260 final AtomicReference<SinkState> mSinkState = new AtomicReference<>(Sink
State.NOT_STARTED); | 267 final AtomicReference<SinkState> mSinkState = new AtomicReference<>(Sink
State.NOT_STARTED); |
261 final Executor mUserUploadExecutor; | 268 final Executor mUserUploadExecutor; |
262 final Executor mExecutor; | 269 final Executor mExecutor; |
263 final HttpURLConnection mUrlConnection; | 270 final HttpURLConnection mUrlConnection; |
264 WritableByteChannel mOutputChannel; | 271 WritableByteChannel mOutputChannel; |
265 OutputStream mUrlConnectionOutputStream; | 272 OutputStream mUrlConnectionOutputStream; |
266 final UploadDataProvider mUploadProvider; | 273 final UploadDataProvider mUploadProvider; |
267 ByteBuffer mBuffer; | 274 ByteBuffer mBuffer; |
268 /** This holds the total bytes to send (the content-length). -1 if unkno
wn. */ | 275 /** This holds the total bytes to send (the content-length). -1 if unkno
wn. */ |
269 long mTotalBytes; | 276 long mTotalBytes; |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 public boolean isDone() { | 758 public boolean isDone() { |
752 State state = mState.get(); | 759 State state = mState.get(); |
753 return state == State.COMPLETE | state == State.ERROR | state == State.C
ANCELLED; | 760 return state == State.COMPLETE | state == State.ERROR | state == State.C
ANCELLED; |
754 } | 761 } |
755 | 762 |
756 @Override | 763 @Override |
757 public void getStatus(StatusListener listener) { | 764 public void getStatus(StatusListener listener) { |
758 State state = mState.get(); | 765 State state = mState.get(); |
759 int extraStatus = this.mAdditionalStatusDetails; | 766 int extraStatus = this.mAdditionalStatusDetails; |
760 | 767 |
761 @Status.StatusValues final int status; | 768 @StatusConverter.StatusValues |
| 769 final int status; |
762 switch (state) { | 770 switch (state) { |
763 case ERROR: | 771 case ERROR: |
764 case COMPLETE: | 772 case COMPLETE: |
765 case CANCELLED: | 773 case CANCELLED: |
766 case NOT_STARTED: | 774 case NOT_STARTED: |
767 status = Status.INVALID; | 775 status = Status.INVALID; |
768 break; | 776 break; |
769 case STARTED: | 777 case STARTED: |
770 status = extraStatus; | 778 status = extraStatus; |
771 break; | 779 break; |
772 case REDIRECT_RECEIVED: | 780 case REDIRECT_RECEIVED: |
773 case AWAITING_FOLLOW_REDIRECT: | 781 case AWAITING_FOLLOW_REDIRECT: |
774 case AWAITING_READ: | 782 case AWAITING_READ: |
775 status = Status.IDLE; | 783 status = Status.IDLE; |
776 break; | 784 break; |
777 case READING: | 785 case READING: |
778 status = Status.READING_RESPONSE; | 786 status = Status.READING_RESPONSE; |
779 break; | 787 break; |
780 default: | 788 default: |
781 throw new IllegalStateException("Switch is exhaustive: " + state
); | 789 throw new IllegalStateException("Switch is exhaustive: " + state
); |
782 } | 790 } |
783 | 791 |
784 mCallbackAsync.sendStatus(listener, status); | 792 mCallbackAsync.sendStatus(listener, status); |
785 } | 793 } |
786 | 794 |
787 /** This wrapper ensures that callbacks are always called on the correct exe
cutor */ | 795 /** This wrapper ensures that callbacks are always called on the correct exe
cutor */ |
788 private final class AsyncUrlRequestCallback { | 796 private final class AsyncUrlRequestCallback { |
789 final UrlRequest.Callback mCallback; | 797 final Callback mCallback; |
790 final Executor mUserExecutor; | 798 final Executor mUserExecutor; |
791 final Executor mFallbackExecutor; | 799 final Executor mFallbackExecutor; |
792 | 800 |
793 AsyncUrlRequestCallback(Callback callback, final Executor userExecutor)
{ | 801 AsyncUrlRequestCallback(Callback callback, final Executor userExecutor)
{ |
794 this.mCallback = callback; | 802 this.mCallback = callback; |
795 if (mAllowDirectExecutor) { | 803 if (mAllowDirectExecutor) { |
796 this.mUserExecutor = userExecutor; | 804 this.mUserExecutor = userExecutor; |
797 this.mFallbackExecutor = null; | 805 this.mFallbackExecutor = null; |
798 } else { | 806 } else { |
799 mUserExecutor = new DirectPreventingExecutor(userExecutor); | 807 mUserExecutor = new DirectPreventingExecutor(userExecutor); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 // Can't throw directly from here, since the delegate execut
or could catch this | 967 // Can't throw directly from here, since the delegate execut
or could catch this |
960 // exception. | 968 // exception. |
961 mExecutedInline = new InlineExecutionProhibitedException(); | 969 mExecutedInline = new InlineExecutionProhibitedException(); |
962 return; | 970 return; |
963 } | 971 } |
964 mCommand.run(); | 972 mCommand.run(); |
965 } | 973 } |
966 } | 974 } |
967 } | 975 } |
968 } | 976 } |
OLD | NEW |