Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 android.os.ConditionVariable; | 7 import android.os.ConditionVariable; | 
| 8 import android.os.StrictMode; | 8 import android.os.StrictMode; | 
| 9 | 9 | 
| 10 import static junit.framework.Assert.assertEquals; | 10 import static junit.framework.Assert.assertEquals; | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 public boolean mOnCanceledCalled = false; | 38 public boolean mOnCanceledCalled = false; | 
| 39 | 39 | 
| 40 public int mHttpResponseDataLength = 0; | 40 public int mHttpResponseDataLength = 0; | 
| 41 public String mResponseAsString = ""; | 41 public String mResponseAsString = ""; | 
| 42 | 42 | 
| 43 private static final int READ_BUFFER_SIZE = 32 * 1024; | 43 private static final int READ_BUFFER_SIZE = 32 * 1024; | 
| 44 | 44 | 
| 45 // When false, the consumer is responsible for all calls into the request | 45 // When false, the consumer is responsible for all calls into the request | 
| 46 // that advance it. | 46 // that advance it. | 
| 47 private boolean mAutoAdvance = true; | 47 private boolean mAutoAdvance = true; | 
| 48 // Whether an exception is thrown by maybeThrowCancelOrPause(). | |
| 49 private boolean mListenerExceptionThrown; | |
| 48 | 50 | 
| 49 // Conditionally fail on certain steps. | 51 // Conditionally fail on certain steps. | 
| 50 private FailureType mFailureType = FailureType.NONE; | 52 private FailureType mFailureType = FailureType.NONE; | 
| 51 private ResponseStep mFailureStep = ResponseStep.NOTHING; | 53 private ResponseStep mFailureStep = ResponseStep.NOTHING; | 
| 52 | 54 | 
| 53 // Signals when request is done either successfully or not. | 55 // Signals when request is done either successfully or not. | 
| 54 private final ConditionVariable mDone = new ConditionVariable(); | 56 private final ConditionVariable mDone = new ConditionVariable(); | 
| 55 | 57 | 
| 56 // Signaled on each step when mAutoAdvance is false. | 58 // Signaled on each step when mAutoAdvance is false. | 
| 57 private final ConditionVariable mStepBlock = new ConditionVariable(); | 59 private final ConditionVariable mStepBlock = new ConditionVariable(); | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 84 }); | 86 }); | 
| 85 return mExecutorThread; | 87 return mExecutorThread; | 
| 86 } | 88 } | 
| 87 } | 89 } | 
| 88 | 90 | 
| 89 public enum ResponseStep { | 91 public enum ResponseStep { | 
| 90 NOTHING, | 92 NOTHING, | 
| 91 ON_RECEIVED_REDIRECT, | 93 ON_RECEIVED_REDIRECT, | 
| 92 ON_RESPONSE_STARTED, | 94 ON_RESPONSE_STARTED, | 
| 93 ON_READ_COMPLETED, | 95 ON_READ_COMPLETED, | 
| 94 ON_SUCCEEDED | 96 ON_SUCCEEDED, | 
| 97 ON_FAILED, | |
| 98 ON_CANCELED, | |
| 95 } | 99 } | 
| 96 | 100 | 
| 97 public enum FailureType { | 101 public enum FailureType { | 
| 98 NONE, | 102 NONE, | 
| 99 CANCEL_SYNC, | 103 CANCEL_SYNC, | 
| 100 CANCEL_ASYNC, | 104 CANCEL_ASYNC, | 
| 101 // Same as above, but continues to advance the request after posting | 105 // Same as above, but continues to advance the request after posting | 
| 102 // the cancellation task. | 106 // the cancellation task. | 
| 103 CANCEL_ASYNC_WITHOUT_PAUSE, | 107 CANCEL_ASYNC_WITHOUT_PAUSE, | 
| 104 THROW_SYNC | 108 THROW_SYNC | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 @Override | 215 @Override | 
| 212 public void onFailed(UrlRequest request, UrlResponseInfo info, UrlRequestExc eption error) { | 216 public void onFailed(UrlRequest request, UrlResponseInfo info, UrlRequestExc eption error) { | 
| 213 assertEquals(mExecutorThread, Thread.currentThread()); | 217 assertEquals(mExecutorThread, Thread.currentThread()); | 
| 214 assertTrue(request.isDone()); | 218 assertTrue(request.isDone()); | 
| 215 // Shouldn't happen after success. | 219 // Shouldn't happen after success. | 
| 216 assertTrue(mResponseStep != ResponseStep.ON_SUCCEEDED); | 220 assertTrue(mResponseStep != ResponseStep.ON_SUCCEEDED); | 
| 217 // Should happen at most once for a single request. | 221 // Should happen at most once for a single request. | 
| 218 assertFalse(mOnErrorCalled); | 222 assertFalse(mOnErrorCalled); | 
| 219 assertFalse(mOnCanceledCalled); | 223 assertFalse(mOnCanceledCalled); | 
| 220 assertNull(mError); | 224 assertNull(mError); | 
| 221 if (mFailureType == FailureType.THROW_SYNC) { | 225 if (mListenerExceptionThrown) { | 
| 222 assertEquals(UrlRequestError.LISTENER_EXCEPTION_THROWN, error.getErr orCode()); | 226 assertEquals(UrlRequestError.LISTENER_EXCEPTION_THROWN, error.getErr orCode()); | 
| 223 assertEquals(0, error.getCronetInternalErrorCode()); | 227 assertEquals(0, error.getCronetInternalErrorCode()); | 
| 224 assertEquals("Exception received from UrlRequest.Callback", error.ge tMessage()); | 228 assertEquals("Exception received from UrlRequest.Callback", error.ge tMessage()); | 
| 225 assertNotNull(error.getCause()); | 229 assertNotNull(error.getCause()); | 
| 226 assertTrue(error.getCause() instanceof IllegalStateException); | 230 assertTrue(error.getCause() instanceof IllegalStateException); | 
| 227 assertEquals("Listener Exception.", error.getCause().getMessage()); | 231 assertEquals("Listener Exception.", error.getCause().getMessage()); | 
| 228 assertFalse(error.immediatelyRetryable()); | 232 assertFalse(error.immediatelyRetryable()); | 
| 229 } | 233 } | 
| 230 | 234 | 
| 235 mResponseStep = ResponseStep.ON_FAILED; | |
| 231 mOnErrorCalled = true; | 236 mOnErrorCalled = true; | 
| 232 mError = error; | 237 mError = error; | 
| 233 openDone(); | 238 openDone(); | 
| 234 maybeThrowCancelOrPause(request); | 239 maybeThrowCancelOrPause(request); | 
| 235 } | 240 } | 
| 236 | 241 | 
| 237 @Override | 242 @Override | 
| 238 public void onCanceled(UrlRequest request, UrlResponseInfo info) { | 243 public void onCanceled(UrlRequest request, UrlResponseInfo info) { | 
| 239 assertEquals(mExecutorThread, Thread.currentThread()); | 244 assertEquals(mExecutorThread, Thread.currentThread()); | 
| 240 assertTrue(request.isDone()); | 245 assertTrue(request.isDone()); | 
| 241 // Should happen at most once for a single request. | 246 // Should happen at most once for a single request. | 
| 242 assertFalse(mOnCanceledCalled); | 247 assertFalse(mOnCanceledCalled); | 
| 243 assertFalse(mOnErrorCalled); | 248 assertFalse(mOnErrorCalled); | 
| 244 assertNull(mError); | 249 assertNull(mError); | 
| 245 | 250 | 
| 251 mResponseStep = ResponseStep.ON_CANCELED; | |
| 246 mOnCanceledCalled = true; | 252 mOnCanceledCalled = true; | 
| 247 openDone(); | 253 openDone(); | 
| 248 maybeThrowCancelOrPause(request); | 254 maybeThrowCancelOrPause(request); | 
| 249 } | 255 } | 
| 250 | 256 | 
| 251 public void startNextRead(UrlRequest request) { | 257 public void startNextRead(UrlRequest request) { | 
| 252 startNextRead(request, ByteBuffer.allocateDirect(READ_BUFFER_SIZE)); | 258 startNextRead(request, ByteBuffer.allocateDirect(READ_BUFFER_SIZE)); | 
| 253 } | 259 } | 
| 254 | 260 | 
| 255 public void startNextRead(UrlRequest request, ByteBuffer buffer) { | 261 public void startNextRead(UrlRequest request, ByteBuffer buffer) { | 
| 256 mBufferPositionBeforeRead = buffer.position(); | 262 mBufferPositionBeforeRead = buffer.position(); | 
| 257 request.read(buffer); | 263 request.read(buffer); | 
| 258 } | 264 } | 
| 259 | 265 | 
| 260 public boolean isDone() { | 266 public boolean isDone() { | 
| 261 // It's not mentioned by the Android docs, but block(0) seems to block | 267 // It's not mentioned by the Android docs, but block(0) seems to block | 
| 262 // indefinitely, so have to block for one millisecond to get state | 268 // indefinitely, so have to block for one millisecond to get state | 
| 263 // without blocking. | 269 // without blocking. | 
| 264 return mDone.block(1); | 270 return mDone.block(1); | 
| 265 } | 271 } | 
| 266 | 272 | 
| 267 protected void openDone() { | 273 protected void openDone() { | 
| 268 mDone.open(); | 274 mDone.open(); | 
| 269 } | 275 } | 
| 270 | 276 | 
| 271 /** | 277 /** | 
| 272 * Returns {@code false} if the listener should continue to advance the | 278 * Returns {@code false} if the listener should continue to advance the | 
| 273 * request. | 279 * request. | 
| 274 */ | 280 */ | 
| 275 private boolean maybeThrowCancelOrPause(final UrlRequest request) { | 281 private boolean maybeThrowCancelOrPause(final UrlRequest request) { | 
| 
 
kapishnikov
2016/08/31 18:10:27
Maybe we should add
assertEquals(mExecutorThread,
 
xunjieli
2016/08/31 20:03:07
Done.
 
 | |
| 276 if (mResponseStep != mFailureStep || mFailureType == FailureType.NONE) { | 282 if (mResponseStep != mFailureStep || mFailureType == FailureType.NONE) { | 
| 277 if (!mAutoAdvance) { | 283 if (!mAutoAdvance) { | 
| 278 mStepBlock.open(); | 284 mStepBlock.open(); | 
| 279 return true; | 285 return true; | 
| 280 } | 286 } | 
| 281 return false; | 287 return false; | 
| 282 } | 288 } | 
| 283 | 289 | 
| 284 if (mFailureType == FailureType.THROW_SYNC) { | 290 if (mFailureType == FailureType.THROW_SYNC) { | 
| 291 assertFalse(mListenerExceptionThrown); | |
| 292 mListenerExceptionThrown = true; | |
| 285 throw new IllegalStateException("Listener Exception."); | 293 throw new IllegalStateException("Listener Exception."); | 
| 286 } | 294 } | 
| 287 Runnable task = new Runnable() { | 295 Runnable task = new Runnable() { | 
| 288 public void run() { | 296 public void run() { | 
| 289 request.cancel(); | 297 request.cancel(); | 
| 290 } | 298 } | 
| 291 }; | 299 }; | 
| 292 if (mFailureType == FailureType.CANCEL_ASYNC | 300 if (mFailureType == FailureType.CANCEL_ASYNC | 
| 293 || mFailureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE) { | 301 || mFailureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE) { | 
| 294 getExecutor().execute(task); | 302 getExecutor().execute(task); | 
| 295 } else { | 303 } else { | 
| 296 task.run(); | 304 task.run(); | 
| 297 } | 305 } | 
| 298 return mFailureType != FailureType.CANCEL_ASYNC_WITHOUT_PAUSE; | 306 return mFailureType != FailureType.CANCEL_ASYNC_WITHOUT_PAUSE; | 
| 299 } | 307 } | 
| 300 } | 308 } | 
| OLD | NEW |