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 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; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 if (mUploadDataStreamAdapter == 0) { | 48 if (mUploadDataStreamAdapter == 0) { |
49 return; | 49 return; |
50 } | 50 } |
51 checkState(UserCallback.NOT_IN_CALLBACK); | 51 checkState(UserCallback.NOT_IN_CALLBACK); |
52 if (mByteBuffer == null) { | 52 if (mByteBuffer == null) { |
53 throw new IllegalStateException("Unexpected readData call. B
uffer is null"); | 53 throw new IllegalStateException("Unexpected readData call. B
uffer is null"); |
54 } | 54 } |
55 mInWhichUserCallback = UserCallback.READ; | 55 mInWhichUserCallback = UserCallback.READ; |
56 } | 56 } |
57 try { | 57 try { |
| 58 checkCallingThread(); |
58 mDataProvider.read(CronetUploadDataStream.this, mByteBuffer); | 59 mDataProvider.read(CronetUploadDataStream.this, mByteBuffer); |
59 } catch (Exception exception) { | 60 } catch (Exception exception) { |
60 onError(exception); | 61 onError(exception); |
61 } | 62 } |
62 } | 63 } |
63 }; | 64 }; |
64 | 65 |
65 // ByteBuffer created in the native code and passed to | 66 // ByteBuffer created in the native code and passed to |
66 // UploadDataProvider for reading. It is only valid from the | 67 // UploadDataProvider for reading. It is only valid from the |
67 // call to mDataProvider.read until onError or onReadSucceeded. | 68 // call to mDataProvider.read until onError or onReadSucceeded. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 @Override | 124 @Override |
124 public void run() { | 125 public void run() { |
125 synchronized (mLock) { | 126 synchronized (mLock) { |
126 if (mUploadDataStreamAdapter == 0) { | 127 if (mUploadDataStreamAdapter == 0) { |
127 return; | 128 return; |
128 } | 129 } |
129 checkState(UserCallback.NOT_IN_CALLBACK); | 130 checkState(UserCallback.NOT_IN_CALLBACK); |
130 mInWhichUserCallback = UserCallback.REWIND; | 131 mInWhichUserCallback = UserCallback.REWIND; |
131 } | 132 } |
132 try { | 133 try { |
| 134 checkCallingThread(); |
133 mDataProvider.rewind(CronetUploadDataStream.this); | 135 mDataProvider.rewind(CronetUploadDataStream.this); |
134 } catch (Exception exception) { | 136 } catch (Exception exception) { |
135 onError(exception); | 137 onError(exception); |
136 } | 138 } |
137 } | 139 } |
138 }; | 140 }; |
139 postTaskToExecutor(task); | 141 postTaskToExecutor(task); |
140 } | 142 } |
141 | 143 |
| 144 private void checkCallingThread() { |
| 145 if (mRequest != null) { |
| 146 mRequest.checkCallingThread(); |
| 147 } |
| 148 } |
| 149 |
142 @GuardedBy("mLock") | 150 @GuardedBy("mLock") |
143 private void checkState(UserCallback mode) { | 151 private void checkState(UserCallback mode) { |
144 if (mInWhichUserCallback != mode) { | 152 if (mInWhichUserCallback != mode) { |
145 throw new IllegalStateException( | 153 throw new IllegalStateException( |
146 "Expected " + mode + ", but was " + mInWhichUserCallback); | 154 "Expected " + mode + ", but was " + mInWhichUserCallback); |
147 } | 155 } |
148 } | 156 } |
149 | 157 |
150 /** | 158 /** |
151 * Called when the native UploadDataStream is destroyed. At this point, | 159 * Called when the native UploadDataStream is destroyed. At this point, |
152 * the native adapter needs to be destroyed, but only after any pending | 160 * the native adapter needs to be destroyed, but only after any pending |
153 * read operation completes, as the adapter owns the read buffer. | 161 * read operation completes, as the adapter owns the read buffer. |
154 */ | 162 */ |
155 @SuppressWarnings("unused") | 163 @SuppressWarnings("unused") |
156 @CalledByNative | 164 @CalledByNative |
157 void onUploadDataStreamDestroyed() { | 165 void onUploadDataStreamDestroyed() { |
158 destroyAdapter(); | 166 destroyAdapter(); |
159 } | 167 } |
160 | 168 |
161 /** | 169 /** |
162 * Helper method called when an exception occurred. This method resets | 170 * Helper method called when an exception occurred. This method resets |
163 * states and propagates the error to the request. | 171 * states and propagates the error to the request. |
164 */ | 172 */ |
165 private void onError(Throwable exception) { | 173 private void onError(Throwable exception) { |
| 174 final boolean sendClose; |
166 synchronized (mLock) { | 175 synchronized (mLock) { |
167 if (mInWhichUserCallback == UserCallback.NOT_IN_CALLBACK) { | 176 if (mInWhichUserCallback == UserCallback.NOT_IN_CALLBACK) { |
168 throw new IllegalStateException( | 177 throw new IllegalStateException( |
169 "There is no read or rewind or length check in progress.
"); | 178 "There is no read or rewind or length check in progress.
"); |
170 } | 179 } |
| 180 sendClose = mInWhichUserCallback == UserCallback.GET_LENGTH; |
171 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK; | 181 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK; |
172 mByteBuffer = null; | 182 mByteBuffer = null; |
173 destroyAdapterIfPostponed(); | 183 destroyAdapterIfPostponed(); |
174 } | 184 } |
| 185 // Failure before length is obtained means that the request has failed b
efore the |
| 186 // adapter has been initialized. Close the UploadDataProvider. This is s
afe to call |
| 187 // here since failure during getLength can only happen on the user's exe
cutor. |
| 188 if (sendClose) { |
| 189 try { |
| 190 mDataProvider.close(); |
| 191 } catch (Exception e) { |
| 192 Log.e(TAG, "Failure closing data provider", e); |
| 193 } |
| 194 } |
175 | 195 |
176 // Just fail the request - simpler to fail directly, and | 196 // Just fail the request - simpler to fail directly, and |
177 // UploadDataStream only supports failing during initialization, not | 197 // UploadDataStream only supports failing during initialization, not |
178 // while reading. The request is smart enough to handle the case where | 198 // while reading. The request is smart enough to handle the case where |
179 // it was already canceled by the embedder. | 199 // it was already canceled by the embedder. |
180 mRequest.onUploadException(exception); | 200 mRequest.onUploadException(exception); |
181 } | 201 } |
182 | 202 |
183 @Override | 203 @Override |
184 public void onReadSucceeded(boolean lastChunk) { | 204 public void onReadSucceeded(boolean lastChunk) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 nativeDestroy(mUploadDataStreamAdapter); | 287 nativeDestroy(mUploadDataStreamAdapter); |
268 mUploadDataStreamAdapter = 0; | 288 mUploadDataStreamAdapter = 0; |
269 if (mOnDestroyedCallbackForTesting != null) { | 289 if (mOnDestroyedCallbackForTesting != null) { |
270 mOnDestroyedCallbackForTesting.run(); | 290 mOnDestroyedCallbackForTesting.run(); |
271 } | 291 } |
272 } | 292 } |
273 postTaskToExecutor(new Runnable() { | 293 postTaskToExecutor(new Runnable() { |
274 @Override | 294 @Override |
275 public void run() { | 295 public void run() { |
276 try { | 296 try { |
| 297 checkCallingThread(); |
277 mDataProvider.close(); | 298 mDataProvider.close(); |
278 } catch (IOException e) { | 299 } catch (Exception e) { |
279 Log.e(TAG, "Exception thrown when closing", e); | 300 Log.e(TAG, "Exception thrown when closing", e); |
280 } | 301 } |
281 } | 302 } |
282 }); | 303 }); |
283 } | 304 } |
284 | 305 |
285 /** | 306 /** |
286 * Destroys the native adapter if the destruction is postponed due to a | 307 * Destroys the native adapter if the destruction is postponed due to a |
287 * pending read, which has since completed. Caller needs to be on executor | 308 * pending read, which has since completed. Caller needs to be on executor |
288 * thread. | 309 * thread. |
289 */ | 310 */ |
290 private void destroyAdapterIfPostponed() { | 311 private void destroyAdapterIfPostponed() { |
291 synchronized (mLock) { | 312 synchronized (mLock) { |
292 if (mInWhichUserCallback == UserCallback.READ) { | 313 if (mInWhichUserCallback == UserCallback.READ) { |
293 throw new IllegalStateException( | 314 throw new IllegalStateException( |
294 "Method should not be called when read has not completed
."); | 315 "Method should not be called when read has not completed
."); |
295 } | 316 } |
296 if (mDestroyAdapterPostponed) { | 317 if (mDestroyAdapterPostponed) { |
297 destroyAdapter(); | 318 destroyAdapter(); |
298 } | 319 } |
299 } | 320 } |
300 } | 321 } |
301 | 322 |
302 /** | 323 /** |
303 * Initializes upload length by getting it from data provider. Always called | 324 * Initializes upload length by getting it from data provider. Submits to |
304 * on executor thread to allow getLength() to block and/or report errors. | 325 * the user's executor thread to allow getLength() to block and/or report er
rors. |
305 * If data provider throws an exception, then it is reported to the request. | 326 * If data provider throws an exception, then it is reported to the request. |
306 * No native calls to urlRequest are allowed as this is done before request | 327 * No native calls to urlRequest are allowed as this is done before request |
307 * start, so native object may not exist. | 328 * start, so native object may not exist. |
308 */ | 329 */ |
309 void initializeWithRequest(final CronetUrlRequest urlRequest) { | 330 void initializeWithRequest(final CronetUrlRequest urlRequest) { |
310 synchronized (mLock) { | 331 synchronized (mLock) { |
311 mRequest = urlRequest; | 332 mRequest = urlRequest; |
312 mInWhichUserCallback = UserCallback.GET_LENGTH; | 333 mInWhichUserCallback = UserCallback.GET_LENGTH; |
313 } | 334 } |
314 try { | 335 try { |
| 336 urlRequest.checkCallingThread(); |
315 mLength = mDataProvider.getLength(); | 337 mLength = mDataProvider.getLength(); |
316 mRemainingLength = mLength; | 338 mRemainingLength = mLength; |
317 } catch (Throwable t) { | 339 } catch (Throwable t) { |
318 onError(t); | 340 onError(t); |
319 } | 341 } |
320 synchronized (mLock) { | 342 synchronized (mLock) { |
321 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK; | 343 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK; |
322 } | 344 } |
323 } | 345 } |
324 | 346 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 | 384 |
363 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") | 385 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") |
364 private native void nativeOnReadSucceeded(long nativePtr, int bytesRead, boo
lean finalChunk); | 386 private native void nativeOnReadSucceeded(long nativePtr, int bytesRead, boo
lean finalChunk); |
365 | 387 |
366 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") | 388 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") |
367 private native void nativeOnRewindSucceeded(long nativePtr); | 389 private native void nativeOnRewindSucceeded(long nativePtr); |
368 | 390 |
369 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") | 391 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") |
370 private static native void nativeDestroy(long nativePtr); | 392 private static native void nativeDestroy(long nativePtr); |
371 } | 393 } |
OLD | NEW |