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
3 // found in the LICENSE file.
5 package org.chromium.cronet_test_apk;
7 import android.os.ConditionVariable;
9 import static junit.framework.Assert.assertEquals;
10 import static junit.framework.Assert.assertTrue;
12 import org.chromium.net.ExtendedResponseInfo;
13 import org.chromium.net.ResponseInfo;
14 import org.chromium.net.UrlRequest;
15 import org.chromium.net.UrlRequestException;
16 import org.chromium.net.UrlRequestListener;
18 import java.nio.ByteBuffer;
19 import java.util.ArrayList;
20 import java.util.concurrent.Executor;
21 import java.util.concurrent.ExecutorService;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.ThreadFactory;
26 * Listener that tracks information from different callbacks and and has a
27 * method to block thread until the request completes on another thread.
28 * Allows to cancel, block request or throw an exception from an arbitrary step.
30 class TestUrlRequestListener implements UrlRequestListener {
31 public ArrayList<ResponseInfo> mRedirectResponseInfoList =
32 new ArrayList<ResponseInfo>();
33 public ResponseInfo mResponseInfo;
34 public ExtendedResponseInfo mExtendedResponseInfo;
35 public UrlRequestException mError;
37 public ResponseStep mResponseStep = ResponseStep.NOTHING;
39 public boolean mOnRedirectCalled = false;
40 public boolean mOnErrorCalled = false;
42 public int mHttpResponseDataLength = 0;
43 public byte[] mLastDataReceivedAsBytes;
44 public String mResponseAsString = "";
46 // Conditionally fail on certain steps.
47 private FailureType mFailureType = FailureType.NONE;
48 private ResponseStep mFailureStep = ResponseStep.NOTHING;
50 // Signals when request is done either successfully or not.
51 private ConditionVariable mDone = new ConditionVariable();
52 private ConditionVariable mStepBlock = new ConditionVariable(true);
54 // Executor for Cronet callbacks.
55 ExecutorService mExecutor = Executors.newSingleThreadExecutor(
56 new ExecutorThreadFactory());
57 Thread mExecutorThread;
59 private class ExecutorThreadFactory implements ThreadFactory {
60 public Thread newThread(Runnable r) {
61 mExecutorThread = new Thread(r);
62 return mExecutorThread;
66 public enum ResponseStep {
74 public enum FailureType {
82 public TestUrlRequestListener() {
85 public void setFailure(FailureType failureType, ResponseStep failureStep) {
86 mFailureStep = failureStep;
87 mFailureType = failureType;
88 if (failureType == FailureType.BLOCK) {
93 public void blockForDone() {
97 public void openBlockedStep() {
101 public Executor getExecutor() {
106 public void onRedirect(UrlRequest request,
108 String newLocationUrl) {
109 assertEquals(mExecutorThread, Thread.currentThread());
110 assertTrue(mResponseStep == ResponseStep.NOTHING
111 || mResponseStep == ResponseStep.ON_REDIRECT);
112 mRedirectResponseInfoList.add(info);
113 mResponseStep = ResponseStep.ON_REDIRECT;
114 mOnRedirectCalled = true;
115 maybeThrowOrCancel(request);
119 public void onResponseStarted(UrlRequest request, ResponseInfo info) {
120 assertEquals(mExecutorThread, Thread.currentThread());
121 assertTrue(mResponseStep == ResponseStep.NOTHING
122 || mResponseStep == ResponseStep.ON_REDIRECT);
123 mResponseStep = ResponseStep.ON_RESPONSE_STARTED;
124 mResponseInfo = info;
125 maybeThrowOrCancel(request);
129 public void onDataReceived(UrlRequest request,
131 ByteBuffer byteBuffer) {
132 assertEquals(mExecutorThread, Thread.currentThread());
133 assertTrue(mResponseStep == ResponseStep.ON_RESPONSE_STARTED
134 || mResponseStep == ResponseStep.ON_DATA_RECEIVED);
135 mResponseStep = ResponseStep.ON_DATA_RECEIVED;
137 mHttpResponseDataLength += byteBuffer.capacity();
138 mLastDataReceivedAsBytes = new byte[byteBuffer.capacity()];
139 byteBuffer.get(mLastDataReceivedAsBytes);
140 mResponseAsString += new String(mLastDataReceivedAsBytes);
141 maybeThrowOrCancel(request);
145 public void onSucceeded(UrlRequest request, ExtendedResponseInfo info) {
146 assertEquals(mExecutorThread, Thread.currentThread());
147 assertTrue(mResponseStep == ResponseStep.ON_RESPONSE_STARTED
148 || mResponseStep == ResponseStep.ON_DATA_RECEIVED);
149 mResponseStep = ResponseStep.ON_SUCCEEDED;
150 mExtendedResponseInfo = info;
152 maybeThrowOrCancel(request);
156 public void onFailed(UrlRequest request,
158 UrlRequestException error) {
159 assertEquals(mExecutorThread, Thread.currentThread());
160 mOnErrorCalled = true;
163 maybeThrowOrCancel(request);
166 protected void openDone() {
170 private void maybeThrowOrCancel(final UrlRequest request) {
171 if (mResponseStep != mFailureStep) {
174 if (mFailureType == FailureType.NONE) {
177 if (mFailureType == FailureType.THROW_SYNC) {
178 throw new IllegalStateException("Listener Exception.");
180 Runnable task = new Runnable() {
186 if (mFailureType == FailureType.CANCEL_ASYNC) {
187 mExecutor.execute(task);