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 |