| 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; |
| 6 | 6 |
| 7 import org.chromium.base.CalledByNative; | 7 import org.chromium.base.CalledByNative; |
| 8 import org.chromium.base.JNINamespace; | 8 import org.chromium.base.JNINamespace; |
| 9 import org.chromium.base.NativeClassQualifiedName; | 9 import org.chromium.base.NativeClassQualifiedName; |
| 10 | 10 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 // ByteBuffer created in the native code and passed to | 45 // ByteBuffer created in the native code and passed to |
| 46 // UploadDataProvider for reading. It is only valid from the | 46 // UploadDataProvider for reading. It is only valid from the |
| 47 // call to mDataProvider.read until onError or onReadSucceeded. | 47 // call to mDataProvider.read until onError or onReadSucceeded. |
| 48 private ByteBuffer mByteBuffer = null; | 48 private ByteBuffer mByteBuffer = null; |
| 49 | 49 |
| 50 // Lock that protects all subsequent variables. The delegate has to be | 50 // Lock that protects all subsequent variables. The delegate has to be |
| 51 // protected to ensure safe shutdown, mReading and mRewinding are protected | 51 // protected to ensure safe shutdown, mReading and mRewinding are protected |
| 52 // to robustly detect getting read/rewind results more often than expected. | 52 // to robustly detect getting read/rewind results more often than expected. |
| 53 private final Object mLock = new Object(); | 53 private final Object mLock = new Object(); |
| 54 | 54 |
| 55 // Native adapter delegate object, owned by the CronetUploadDataStream. | 55 // Native delegate object, owned by the CronetUploadDataStream. It's only |
| 56 // It's only deleted after the native UploadDataStream object is destroyed. | 56 // deleted after the native UploadDataStream object is destroyed. All access |
| 57 // All access to the delegate is synchronized, for safe usage and cleanup. | 57 // to the delegate is synchronized, for safe usage and cleanup. |
| 58 private long mUploadDataStreamDelegate = 0; | 58 private long mUploadDataStreamDelegate = 0; |
| 59 | 59 |
| 60 private boolean mReading = false; | 60 private boolean mReading = false; |
| 61 private boolean mRewinding = false; | 61 private boolean mRewinding = false; |
| 62 private boolean mDestroyDelegatePostponed = false; | 62 private boolean mDestroyDelegatePostponed = false; |
| 63 | 63 |
| 64 /** | 64 /** |
| 65 * Constructs a CronetUploadDataStream. | 65 * Constructs a CronetUploadDataStream. |
| 66 * @param dataProvider the UploadDataProvider to read data from. | 66 * @param dataProvider the UploadDataProvider to read data from. |
| 67 * @param executor the Executor to execute UploadDataProvider tasks. | 67 * @param executor the Executor to execute UploadDataProvider tasks. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 mDataProvider.rewind(CronetUploadDataStream.this); | 108 mDataProvider.rewind(CronetUploadDataStream.this); |
| 109 } catch (Exception exception) { | 109 } catch (Exception exception) { |
| 110 onError(exception); | 110 onError(exception); |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 }; | 113 }; |
| 114 mExecutor.execute(task); | 114 mExecutor.execute(task); |
| 115 } | 115 } |
| 116 | 116 |
| 117 /** | 117 /** |
| 118 * Called by native code to destroy the native adapter delegate, when the | 118 * Called when the native UploadDataStream is destroyed. At this point, |
| 119 * adapter is destroyed. | 119 * the native delegate needs to be destroyed, but only after any pending |
| 120 * read operation completes, as the delegate owns the read buffer. |
| 120 */ | 121 */ |
| 121 @SuppressWarnings("unused") | 122 @SuppressWarnings("unused") |
| 122 @CalledByNative | 123 @CalledByNative |
| 123 void onAdapterDestroyed() { | 124 void onUploadDataStreamDestroyed() { |
| 124 Runnable task = new Runnable() { | 125 Runnable task = new Runnable() { |
| 125 @Override | 126 @Override |
| 126 public void run() { | 127 public void run() { |
| 127 destroyDelegate(); | 128 destroyDelegate(); |
| 128 } | 129 } |
| 129 }; | 130 }; |
| 130 | 131 |
| 131 mExecutor.execute(task); | 132 mExecutor.execute(task); |
| 132 } | 133 } |
| 133 | 134 |
| 134 /** | 135 /** |
| 135 * Helper method called when an exception occurred. This method resets | 136 * Helper method called when an exception occurred. This method resets |
| 136 * states and propagates the error to the request. | 137 * states and propagates the error to the request. |
| 137 */ | 138 */ |
| 138 private void onError(Exception exception) { | 139 private void onError(Exception exception) { |
| 139 synchronized (mLock) { | 140 synchronized (mLock) { |
| 140 if (!mReading && !mRewinding) { | 141 if (!mReading && !mRewinding) { |
| 141 throw new IllegalStateException( | 142 throw new IllegalStateException( |
| 142 "There is no read or rewind in progress."); | 143 "There is no read or rewind in progress."); |
| 143 } | 144 } |
| 144 mReading = false; | 145 mReading = false; |
| 145 mRewinding = false; | 146 mRewinding = false; |
| 146 mByteBuffer = null; | 147 mByteBuffer = null; |
| 147 destroyDelegateIfPostponed(); | 148 destroyDelegateIfPostponed(); |
| 148 } | 149 } |
| 149 | 150 |
| 150 // Just fail the request - simpler to fail directly, and | 151 // Just fail the request - simpler to fail directly, and |
| 151 // UploadDataStream only supports failing during initialization, not | 152 // UploadDataStream only supports failing during initialization, not |
| 152 // while reading. This should be safe, even if we deleted the adapter, | 153 // while reading. The request is smart enough to handle the case where |
| 153 // because in that case, the request has already been cancelled. | 154 // it was already cancelled by the embedder. |
| 154 mRequest.onUploadException(exception); | 155 mRequest.onUploadException(exception); |
| 155 } | 156 } |
| 156 | 157 |
| 157 @Override | 158 @Override |
| 158 public void onReadSucceeded(boolean lastChunk) { | 159 public void onReadSucceeded(boolean lastChunk) { |
| 159 synchronized (mLock) { | 160 synchronized (mLock) { |
| 160 if (!mReading) { | 161 if (!mReading) { |
| 161 throw new IllegalStateException("Non-existent read succeeded."); | 162 throw new IllegalStateException("Non-existent read succeeded."); |
| 162 } | 163 } |
| 163 if (lastChunk && mLength >= 0) { | 164 if (lastChunk && mLength >= 0) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 * an interface with just this method, to minimize CronetURLRequest's | 260 * an interface with just this method, to minimize CronetURLRequest's |
| 260 * dependencies on each upload stream type. | 261 * dependencies on each upload stream type. |
| 261 */ | 262 */ |
| 262 void attachToRequest(CronetUrlRequest request, long requestAdapter) { | 263 void attachToRequest(CronetUrlRequest request, long requestAdapter) { |
| 263 mRequest = request; | 264 mRequest = request; |
| 264 mUploadDataStreamDelegate = | 265 mUploadDataStreamDelegate = |
| 265 nativeAttachUploadDataToRequest(requestAdapter, mLength); | 266 nativeAttachUploadDataToRequest(requestAdapter, mLength); |
| 266 } | 267 } |
| 267 | 268 |
| 268 /** | 269 /** |
| 269 * Creates a native UploadDataStreamDelegate and UploadDataStreamAdapter | 270 * Creates a native CronetUploadDataStreamDelegate and |
| 270 * for testing. | 271 * CronetUploadDataStream for testing. |
| 271 * @return the address of the native CronetUploadDataStreamAdapter object. | 272 * @return the address of the native CronetUploadDataStream object. |
| 272 */ | 273 */ |
| 273 public long createAdapterForTesting() { | 274 public long createUploadDataStreamForTesting() { |
| 274 mUploadDataStreamDelegate = nativeCreateDelegateForTesting(); | 275 mUploadDataStreamDelegate = nativeCreateDelegateForTesting(); |
| 275 return nativeCreateAdapterForTesting(mLength, mUploadDataStreamDelegate)
; | 276 return nativeCreateUploadDataStreamForTesting(mLength, |
| 277 mUploadDataStreamDelegate); |
| 276 } | 278 } |
| 277 | 279 |
| 278 // Native methods are implemented in upload_data_stream_adapter.cc. | 280 // Native methods are implemented in upload_data_stream.cc. |
| 279 | 281 |
| 280 private native long nativeAttachUploadDataToRequest(long urlRequestAdapter, | 282 private native long nativeAttachUploadDataToRequest(long urlRequestAdapter, |
| 281 long length); | 283 long length); |
| 282 | 284 |
| 283 private native long nativeCreateDelegateForTesting(); | 285 private native long nativeCreateDelegateForTesting(); |
| 284 | 286 |
| 285 private native long nativeCreateAdapterForTesting(long length, | 287 private native long nativeCreateUploadDataStreamForTesting(long length, |
| 286 long delegate); | 288 long delegate); |
| 287 | 289 |
| 288 @NativeClassQualifiedName("CronetUploadDataStreamDelegate") | 290 @NativeClassQualifiedName("CronetUploadDataStreamDelegate") |
| 289 private native void nativeOnReadSucceeded(long nativePtr, | 291 private native void nativeOnReadSucceeded(long nativePtr, |
| 290 int bytesRead, boolean finalChunk); | 292 int bytesRead, boolean finalChunk); |
| 291 | 293 |
| 292 @NativeClassQualifiedName("CronetUploadDataStreamDelegate") | 294 @NativeClassQualifiedName("CronetUploadDataStreamDelegate") |
| 293 private native void nativeOnRewindSucceeded(long nativePtr); | 295 private native void nativeOnRewindSucceeded(long nativePtr); |
| 294 | 296 |
| 295 private static native void nativeDestroyDelegate( | 297 private static native void nativeDestroyDelegate( |
| 296 long uploadDataStreamDelegate); | 298 long uploadDataStreamDelegate); |
| 297 } | 299 } |
| OLD | NEW |