Index: components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java |
diff --git a/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f22dbe1fe0331b8e4856848360a5a9a75eb78824 |
--- /dev/null |
+++ b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestUrlRequestListener.java |
@@ -0,0 +1,193 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.cronet_test_apk; |
+ |
+import android.os.ConditionVariable; |
+ |
+import org.chromium.net.ExtendedResponseInfo; |
+import org.chromium.net.ResponseInfo; |
+import org.chromium.net.UrlRequest; |
+import org.chromium.net.UrlRequestException; |
+import org.chromium.net.UrlRequestListener; |
+ |
+import java.nio.ByteBuffer; |
+import java.util.ArrayList; |
+import java.util.concurrent.Executor; |
+import java.util.concurrent.ExecutorService; |
+import java.util.concurrent.Executors; |
+import java.util.concurrent.ThreadFactory; |
+ |
+import static junit.framework.Assert.assertEquals; |
+import static junit.framework.Assert.assertTrue; |
+ |
+/** |
+ * Listener that tracks information from different callbacks and and has a |
+ * method to block until thread until the request completes on another thread. |
xunjieli
2014/10/31 21:01:51
nit: there are two "until"
mef
2014/10/31 21:43:16
Done.
|
+ * Allows to cancel, block request or throw an exception from an arbitrary step. |
+ */ |
+class TestUrlRequestListener implements UrlRequestListener { |
+ public ArrayList<ResponseInfo> mRedirectResponseInfoList = |
+ new ArrayList<ResponseInfo>(); |
+ public ResponseInfo mResponseInfo; |
+ public ExtendedResponseInfo mExtendedResponseInfo; |
+ public UrlRequestException mError; |
+ |
+ public LastCalled mLastCalled = LastCalled.Nothing; |
+ |
+ public boolean mOnRedirectCalled = false; |
+ public boolean mOnErrorCalled = false; |
+ |
+ public int mHttpResponseDataLength = 0; |
+ public byte[] mLastDataReceivedAsBytes; |
+ public String mResponseAsString = ""; |
+ |
+ // Conditionally fail on certain steps. |
+ private FailureType mFailureType = FailureType.None; |
+ private LastCalled mFailureStep = LastCalled.Nothing; |
+ |
+ // Signals when request is done either successfully or not. |
+ private ConditionVariable mDone = new ConditionVariable(); |
+ private ConditionVariable mStepBlock = new ConditionVariable(true); |
+ |
+ // Executor for Cronet callbacks. |
+ ExecutorService mExecutor = Executors.newSingleThreadExecutor( |
+ new ExecutorThreadFactory()); |
+ Thread mExecutorThread; |
+ |
+ private class ExecutorThreadFactory implements ThreadFactory { |
+ public Thread newThread(Runnable r) { |
+ mExecutorThread = new Thread(r); |
+ return mExecutorThread; |
+ } |
+ } |
+ |
+ public enum LastCalled { |
+ Nothing, |
+ OnRedirect, |
+ OnResponseStarted, |
+ OnDataReceived, |
+ OnComplete |
xunjieli
2014/10/31 21:01:51
Since onError is not a part of this enum, does it
mef
2014/10/31 21:43:16
Hmm, it is also used in asserts below to verify co
xunjieli
2014/11/03 14:26:05
I see. Another nit, Enum constants should be upper
mef
2014/11/03 16:42:19
Great point, done.
|
+ }; |
+ |
+ public enum FailureType { |
+ None, |
+ Block, |
+ CancelSync, |
+ CancelAsync, |
+ ThrowSync |
+ }; |
+ |
+ public TestUrlRequestListener() { |
+ } |
+ |
+ public void setFailure(FailureType failureType, LastCalled failureStep) { |
+ mFailureStep = failureStep; |
+ mFailureType = failureType; |
+ if (failureType == FailureType.Block) { |
+ mStepBlock.close(); |
+ } |
+ } |
+ |
+ public void blockForDone() { |
+ mDone.block(); |
+ } |
+ |
+ public void openBlockedStep() { |
+ mStepBlock.open(); |
+ } |
+ |
+ public Executor getExecutor() { |
+ return mExecutor; |
+ } |
+ |
+ @Override |
+ public void onRedirect(UrlRequest request, |
+ ResponseInfo info, |
+ String newLocationUrl) { |
+ assertEquals(mExecutorThread, Thread.currentThread()); |
+ assertTrue(mLastCalled == LastCalled.Nothing |
+ || mLastCalled == LastCalled.OnRedirect); |
+ mRedirectResponseInfoList.add(info); |
+ mLastCalled = LastCalled.OnRedirect; |
+ mOnRedirectCalled = true; |
+ maybeThrowOrCancel(request); |
+ } |
+ |
+ @Override |
+ public void onResponseStarted(UrlRequest request, ResponseInfo info) { |
+ assertEquals(mExecutorThread, Thread.currentThread()); |
+ assertTrue(mLastCalled == LastCalled.Nothing |
+ || mLastCalled == LastCalled.OnRedirect); |
+ mLastCalled = LastCalled.OnResponseStarted; |
+ mResponseInfo = info; |
+ maybeThrowOrCancel(request); |
+ } |
+ |
+ @Override |
+ public void onDataReceived(UrlRequest request, |
+ ResponseInfo info, |
+ ByteBuffer byteBuffer) { |
+ assertEquals(mExecutorThread, Thread.currentThread()); |
+ assertTrue(mLastCalled == LastCalled.OnResponseStarted |
+ || mLastCalled == LastCalled.OnDataReceived); |
+ mLastCalled = LastCalled.OnDataReceived; |
+ |
+ mHttpResponseDataLength += byteBuffer.capacity(); |
+ mLastDataReceivedAsBytes = new byte[byteBuffer.capacity()]; |
+ byteBuffer.get(mLastDataReceivedAsBytes); |
+ mResponseAsString += new String(mLastDataReceivedAsBytes); |
+ maybeThrowOrCancel(request); |
+ } |
+ |
+ @Override |
+ public void onSucceeded(UrlRequest request, ExtendedResponseInfo info) { |
+ assertEquals(mExecutorThread, Thread.currentThread()); |
+ assertTrue(mLastCalled == LastCalled.OnResponseStarted |
+ || mLastCalled == LastCalled.OnDataReceived); |
+ mLastCalled = LastCalled.OnComplete; |
+ mExtendedResponseInfo = info; |
+ openDone(); |
+ maybeThrowOrCancel(request); |
+ } |
+ |
+ @Override |
+ public void onFailed(UrlRequest request, |
+ ResponseInfo info, |
xunjieli
2014/10/31 21:01:51
nit: +8 indent.
mef
2014/10/31 21:43:16
Done. I don't like it though...
xunjieli
2014/11/03 14:26:05
I guess you could move "ResponseInfo info" to the
|
+ UrlRequestException error) { |
+ assertEquals(mExecutorThread, Thread.currentThread()); |
+ mOnErrorCalled = true; |
+ mError = error; |
+ openDone(); |
+ maybeThrowOrCancel(request); |
+ } |
+ |
+ protected void openDone() { |
+ mDone.open(); |
+ } |
+ |
+ private void maybeThrowOrCancel(final UrlRequest request) { |
+ if (mLastCalled != mFailureStep) { |
+ return; |
+ } |
+ if (mFailureType == FailureType.None) { |
+ return; |
+ } |
+ if (mFailureType == FailureType.ThrowSync) { |
+ throw new IllegalStateException("Listener Exception."); |
+ } |
+ Runnable task = new Runnable() { |
+ public void run() { |
+ request.cancel(); |
+ openDone(); |
+ } |
+ }; |
+ if (mFailureType == FailureType.CancelAsync) { |
+ mExecutor.execute(task); |
+ } else { |
+ task.run(); |
+ } |
+ } |
+} |
+ |