| Index: components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestDrivenDataProvider.java
|
| diff --git a/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestDrivenDataProvider.java b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestDrivenDataProvider.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fb315b8531f710ecf1aa25712c64dc37873cbf9b
|
| --- /dev/null
|
| +++ b/components/cronet/android/test/javatests/src/org/chromium/cronet_test_apk/TestDrivenDataProvider.java
|
| @@ -0,0 +1,172 @@
|
| +// 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.UploadDataProvider;
|
| +import org.chromium.net.UploadDataSink;
|
| +
|
| +import java.nio.ByteBuffer;
|
| +import java.util.ArrayList;
|
| +import java.util.concurrent.Executor;
|
| +
|
| +class TestDrivenDataProvider implements UploadDataProvider {
|
| + private ArrayList<byte[]> mReads = new ArrayList<byte[]>();
|
| + private final Executor mExecutor;
|
| + private int mNumRewindCalls = 0;
|
| + private int mNumReadCalls = 0;
|
| + private int mNextRead = 0;
|
| +
|
| + private boolean mStarted = false;
|
| + private boolean mReadPending = false;
|
| + private boolean mRewindPending = false;
|
| +
|
| + private ConditionVariable mWaitForReadRequest;
|
| + private ConditionVariable mWaitForRewindRequest;
|
| +
|
| + TestDrivenDataProvider(Executor executor) {
|
| + mExecutor = executor;
|
| + mWaitForReadRequest = new ConditionVariable();
|
| + mWaitForRewindRequest = new ConditionVariable();
|
| + }
|
| +
|
| + // Adds the result to be returned by a successful read request. The
|
| + // returned bytes must all fit within the read buffer provided by Cronet.
|
| + // After a rewind, if there is one, all reads will be repeated.
|
| + public void addRead(byte[] read) {
|
| + if (mStarted) {
|
| + throw new IllegalStateException("Adding bytes after read");
|
| + }
|
| + mReads.add(read);
|
| + }
|
| +
|
| + public int getNumRewindCalls() {
|
| + return mNumRewindCalls;
|
| + }
|
| +
|
| + public void waitForReadRequest() {
|
| + mWaitForReadRequest.block();
|
| + }
|
| +
|
| + public void resetWaitForReadRequest() {
|
| + mWaitForReadRequest.close();
|
| + }
|
| +
|
| + public void waitForRewindRequest() {
|
| + mWaitForRewindRequest.block();
|
| + }
|
| +
|
| + private boolean mReadPendingCopy = false;
|
| +
|
| + // Called on test thread. Check happens on executor thread.
|
| + public boolean checkIfReadPending() {
|
| + final ConditionVariable waitForTaskComplete = new ConditionVariable();
|
| + Runnable task = new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + mReadPendingCopy = mReadPending;
|
| + waitForTaskComplete.open();
|
| + }
|
| + };
|
| + mExecutor.execute(task);
|
| + waitForTaskComplete.block();
|
| + return mReadPendingCopy;
|
| + }
|
| +
|
| + private boolean mRewindPendingCopy = false;
|
| +
|
| + // Called on test thread. Check happens on executor thread.
|
| + public boolean checkIfRewindPending() {
|
| + final ConditionVariable waitForTaskComplete = new ConditionVariable();
|
| + Runnable task = new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + mRewindPendingCopy = mRewindPending;
|
| + waitForTaskComplete.open();
|
| + }
|
| + };
|
| + mExecutor.execute(task);
|
| + waitForTaskComplete.block();
|
| + return mRewindPendingCopy;
|
| + }
|
| +
|
| + // @returns the cumulative length of all data added by calls to addRead.
|
| + @Override
|
| + public long getLength() {
|
| + long length = 0;
|
| + for (byte[] read : mReads) {
|
| + length += read.length;
|
| + }
|
| + return length;
|
| + }
|
| +
|
| + @Override
|
| + public void read(final UploadDataSink uploadDataSink, final ByteBuffer byteBuffer) {
|
| + int currentReadCall = mNumReadCalls;
|
| + ++mNumReadCalls;
|
| + assertIdle();
|
| +
|
| + mReadPending = true;
|
| + mStarted = true;
|
| +
|
| + if (mNextRead != mReads.size()) {
|
| + if (byteBuffer.capacity() < mReads.get(mNextRead).length) {
|
| + throw new IllegalStateException("Read buffer smaller than expected");
|
| + }
|
| + byteBuffer.put(mReads.get(mNextRead));
|
| + byteBuffer.flip();
|
| + ++mNextRead;
|
| + } else {
|
| + throw new IllegalStateException("Too many reads: " + mNextRead);
|
| + }
|
| + mWaitForReadRequest.open();
|
| + }
|
| +
|
| + public void onReadSucceeded(final UploadDataSink uploadDataSink) {
|
| + Runnable completeRunnable = new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + mReadPending = false;
|
| + uploadDataSink.onReadSucceeded(false);
|
| + }
|
| + };
|
| + mExecutor.execute(completeRunnable);
|
| + }
|
| +
|
| + public void rewind(final UploadDataSink uploadDataSink) {
|
| + ++mNumRewindCalls;
|
| + assertIdle();
|
| +
|
| + if (mNextRead == 0) {
|
| + // Should never try and rewind when rewinding does nothing.
|
| + throw new IllegalStateException("Unexpected rewind when already at beginning");
|
| + }
|
| +
|
| + mRewindPending = true;
|
| + mNextRead = 0;
|
| + mWaitForRewindRequest.open();
|
| + }
|
| +
|
| + public void onRewindSucceeded(final UploadDataSink uploadDataSink) {
|
| + Runnable completeRunnable = new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + mRewindPending = false;
|
| + uploadDataSink.onRewindSucceeded();
|
| + }
|
| + };
|
| + mExecutor.execute(completeRunnable);
|
| + }
|
| +
|
| + private void assertIdle() {
|
| + if (mReadPending) {
|
| + throw new IllegalStateException("Unexpected operation during read");
|
| + }
|
| + if (mRewindPending) {
|
| + throw new IllegalStateException("Unexpected operation during rewind");
|
| + }
|
| + }
|
| +}
|
|
|