| 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.util.Log; | 7 import android.util.Log; |
| 8 | 8 |
| 9 import org.chromium.base.VisibleForTesting; | 9 import org.chromium.base.VisibleForTesting; |
| 10 import org.chromium.base.annotations.CalledByNative; | 10 import org.chromium.base.annotations.CalledByNative; |
| 11 import org.chromium.base.annotations.JNINamespace; | 11 import org.chromium.base.annotations.JNINamespace; |
| 12 import org.chromium.base.annotations.NativeClassQualifiedName; | 12 import org.chromium.base.annotations.NativeClassQualifiedName; |
| 13 import org.chromium.net.UploadDataProvider; |
| 14 import org.chromium.net.UploadDataSink; |
| 13 | 15 |
| 14 import java.io.IOException; | 16 import java.io.IOException; |
| 15 import java.nio.ByteBuffer; | 17 import java.nio.ByteBuffer; |
| 16 import java.util.concurrent.Executor; | 18 import java.util.concurrent.Executor; |
| 17 | 19 |
| 18 import javax.annotation.concurrent.GuardedBy; | 20 import javax.annotation.concurrent.GuardedBy; |
| 19 | 21 |
| 20 /** | 22 /** |
| 21 * CronetUploadDataStream handles communication between an upload body | 23 * CronetUploadDataStream handles communication between an upload body |
| 22 * encapsulated in the embedder's {@link UploadDataSink} and a C++ | 24 * encapsulated in the embedder's {@link UploadDataSink} and a C++ |
| 23 * UploadDataStreamAdapter, which it owns. It's attached to a {@link | 25 * UploadDataStreamAdapter, which it owns. It's attached to a {@link |
| 24 * CronetUrlRequest}'s during the construction of request's native C++ objects | 26 * CronetUrlRequest}'s during the construction of request's native C++ objects |
| 25 * on the network thread, though it's created on one of the embedder's threads. | 27 * on the network thread, though it's created on one of the embedder's threads. |
| 26 * It is called by the UploadDataStreamAdapter on the network thread, but calls | 28 * It is called by the UploadDataStreamAdapter on the network thread, but calls |
| 27 * into the UploadDataSink and the UploadDataStreamAdapter on the Executor | 29 * into the UploadDataSink and the UploadDataStreamAdapter on the Executor |
| 28 * passed into its constructor. | 30 * passed into its constructor. |
| 29 */ | 31 */ |
| 30 @JNINamespace("cronet") | 32 @JNINamespace("cronet") |
| 31 final class CronetUploadDataStream implements UploadDataSink { | 33 @VisibleForTesting |
| 34 public final class CronetUploadDataStream implements UploadDataSink { |
| 32 private static final String TAG = "CronetUploadDataStream"; | 35 private static final String TAG = "CronetUploadDataStream"; |
| 33 // These are never changed, once a request starts. | 36 // These are never changed, once a request starts. |
| 34 private final Executor mExecutor; | 37 private final Executor mExecutor; |
| 35 private final UploadDataProvider mDataProvider; | 38 private final UploadDataProvider mDataProvider; |
| 36 private long mLength; | 39 private long mLength; |
| 37 private long mRemainingLength; | 40 private long mRemainingLength; |
| 38 private CronetUrlRequest mRequest; | 41 private CronetUrlRequest mRequest; |
| 39 | 42 |
| 40 // Reusable read task, to reduce redundant memory allocation. | 43 // Reusable read task, to reduce redundant memory allocation. |
| 41 private final Runnable mReadTask = new Runnable() { | 44 private final Runnable mReadTask = new Runnable() { |
| 42 @Override | 45 @Override |
| 43 public void run() { | 46 public void run() { |
| 44 synchronized (mLock) { | 47 synchronized (mLock) { |
| 45 if (mUploadDataStreamAdapter == 0) { | 48 if (mUploadDataStreamAdapter == 0) { |
| 46 return; | 49 return; |
| 47 } | 50 } |
| 48 checkState(UserCallback.NOT_IN_CALLBACK); | 51 checkState(UserCallback.NOT_IN_CALLBACK); |
| 49 if (mByteBuffer == null) { | 52 if (mByteBuffer == null) { |
| 50 throw new IllegalStateException( | 53 throw new IllegalStateException("Unexpected readData call. B
uffer is null"); |
| 51 "Unexpected readData call. Buffer is null"); | |
| 52 } | 54 } |
| 53 mInWhichUserCallback = UserCallback.READ; | 55 mInWhichUserCallback = UserCallback.READ; |
| 54 } | 56 } |
| 55 try { | 57 try { |
| 56 mDataProvider.read(CronetUploadDataStream.this, mByteBuffer); | 58 mDataProvider.read(CronetUploadDataStream.this, mByteBuffer); |
| 57 } catch (Exception exception) { | 59 } catch (Exception exception) { |
| 58 onError(exception); | 60 onError(exception); |
| 59 } | 61 } |
| 60 } | 62 } |
| 61 }; | 63 }; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 // while reading. The request is smart enough to handle the case where | 178 // while reading. The request is smart enough to handle the case where |
| 177 // it was already canceled by the embedder. | 179 // it was already canceled by the embedder. |
| 178 mRequest.onUploadException(exception); | 180 mRequest.onUploadException(exception); |
| 179 } | 181 } |
| 180 | 182 |
| 181 @Override | 183 @Override |
| 182 public void onReadSucceeded(boolean lastChunk) { | 184 public void onReadSucceeded(boolean lastChunk) { |
| 183 synchronized (mLock) { | 185 synchronized (mLock) { |
| 184 checkState(UserCallback.READ); | 186 checkState(UserCallback.READ); |
| 185 if (lastChunk && mLength >= 0) { | 187 if (lastChunk && mLength >= 0) { |
| 186 throw new IllegalArgumentException( | 188 throw new IllegalArgumentException("Non-chunked upload can't hav
e last chunk"); |
| 187 "Non-chunked upload can't have last chunk"); | |
| 188 } | 189 } |
| 189 int bytesRead = mByteBuffer.position(); | 190 int bytesRead = mByteBuffer.position(); |
| 190 mRemainingLength -= bytesRead; | 191 mRemainingLength -= bytesRead; |
| 191 if (mRemainingLength < 0 && mLength >= 0) { | 192 if (mRemainingLength < 0 && mLength >= 0) { |
| 192 throw new IllegalArgumentException( | 193 throw new IllegalArgumentException( |
| 193 String.format("Read upload data length %d exceeds expect
ed length %d", | 194 String.format("Read upload data length %d exceeds expect
ed length %d", |
| 194 mLength - mRemainingLength, mLength)); | 195 mLength - mRemainingLength, mLength)); |
| 195 } | 196 } |
| 196 mByteBuffer = null; | 197 mByteBuffer = null; |
| 197 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK; | 198 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK; |
| 198 | 199 |
| 199 destroyAdapterIfPostponed(); | 200 destroyAdapterIfPostponed(); |
| 200 // Request may been canceled already. | 201 // Request may been canceled already. |
| 201 if (mUploadDataStreamAdapter == 0) { | 202 if (mUploadDataStreamAdapter == 0) { |
| 202 return; | 203 return; |
| 203 } | 204 } |
| 204 nativeOnReadSucceeded(mUploadDataStreamAdapter, bytesRead, | 205 nativeOnReadSucceeded(mUploadDataStreamAdapter, bytesRead, lastChunk
); |
| 205 lastChunk); | |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 | 208 |
| 209 @Override | 209 @Override |
| 210 public void onReadError(Exception exception) { | 210 public void onReadError(Exception exception) { |
| 211 synchronized (mLock) { | 211 synchronized (mLock) { |
| 212 checkState(UserCallback.READ); | 212 checkState(UserCallback.READ); |
| 213 onError(exception); | 213 onError(exception); |
| 214 } | 214 } |
| 215 } | 215 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 mUploadDataStreamAdapter = nativeAttachUploadDataToRequest(requestAd
apter, mLength); | 331 mUploadDataStreamAdapter = nativeAttachUploadDataToRequest(requestAd
apter, mLength); |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 | 334 |
| 335 /** | 335 /** |
| 336 * Creates a native CronetUploadDataStreamAdapter and | 336 * Creates a native CronetUploadDataStreamAdapter and |
| 337 * CronetUploadDataStream for testing. | 337 * CronetUploadDataStream for testing. |
| 338 * @return the address of the native CronetUploadDataStream object. | 338 * @return the address of the native CronetUploadDataStream object. |
| 339 */ | 339 */ |
| 340 @VisibleForTesting | 340 @VisibleForTesting |
| 341 long createUploadDataStreamForTesting() throws IOException { | 341 public long createUploadDataStreamForTesting() throws IOException { |
| 342 synchronized (mLock) { | 342 synchronized (mLock) { |
| 343 mUploadDataStreamAdapter = nativeCreateAdapterForTesting(); | 343 mUploadDataStreamAdapter = nativeCreateAdapterForTesting(); |
| 344 mLength = mDataProvider.getLength(); | 344 mLength = mDataProvider.getLength(); |
| 345 mRemainingLength = mLength; | 345 mRemainingLength = mLength; |
| 346 return nativeCreateUploadDataStreamForTesting(mLength, mUploadDataSt
reamAdapter); | 346 return nativeCreateUploadDataStreamForTesting(mLength, mUploadDataSt
reamAdapter); |
| 347 } | 347 } |
| 348 } | 348 } |
| 349 | 349 |
| 350 @VisibleForTesting | 350 @VisibleForTesting |
| 351 void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackForTesting
) { | 351 void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackForTesting
) { |
| 352 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; | 352 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; |
| 353 } | 353 } |
| 354 | 354 |
| 355 // Native methods are implemented in upload_data_stream_adapter.cc. | 355 // Native methods are implemented in upload_data_stream_adapter.cc. |
| 356 | 356 |
| 357 private native long nativeAttachUploadDataToRequest(long urlRequestAdapter, | 357 private native long nativeAttachUploadDataToRequest(long urlRequestAdapter,
long length); |
| 358 long length); | |
| 359 | 358 |
| 360 private native long nativeCreateAdapterForTesting(); | 359 private native long nativeCreateAdapterForTesting(); |
| 361 | 360 |
| 362 private native long nativeCreateUploadDataStreamForTesting(long length, | 361 private native long nativeCreateUploadDataStreamForTesting(long length, long
adapter); |
| 363 long adapter); | |
| 364 | 362 |
| 365 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") | 363 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") |
| 366 private native void nativeOnReadSucceeded(long nativePtr, | 364 private native void nativeOnReadSucceeded(long nativePtr, int bytesRead, boo
lean finalChunk); |
| 367 int bytesRead, boolean finalChunk); | |
| 368 | 365 |
| 369 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") | 366 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") |
| 370 private native void nativeOnRewindSucceeded(long nativePtr); | 367 private native void nativeOnRewindSucceeded(long nativePtr); |
| 371 | 368 |
| 372 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") | 369 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") |
| 373 private static native void nativeDestroy(long nativePtr); | 370 private static native void nativeDestroy(long nativePtr); |
| 374 } | 371 } |
| OLD | NEW |