Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1140)

Unified Diff: components/cronet/android/java/src/org/chromium/net/UrlRequest.java

Issue 470443005: Cronet modifications to support AGSA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Small changes. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/cronet/android/java/src/org/chromium/net/UrlRequest.java
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequest.java b/components/cronet/android/java/src/org/chromium/net/UrlRequest.java
index 73e9abac4030dd20e16712b8e4dad5d8ea893d22..13cb80306e2236259f297de8e2eb200952f4547f 100644
--- a/components/cronet/android/java/src/org/chromium/net/UrlRequest.java
+++ b/components/cronet/android/java/src/org/chromium/net/UrlRequest.java
@@ -1,13 +1,15 @@
// 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.net;
+import android.os.ConditionVariable;
+
import org.apache.http.conn.ConnectTimeoutException;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -35,24 +37,24 @@ public class UrlRequest {
private final Map<String, String> mHeaders;
private final WritableByteChannel mSink;
private Map<String, String> mAdditionalHeaders;
private String mUploadContentType;
private String mMethod;
private byte[] mUploadData;
private ReadableByteChannel mUploadChannel;
- private WritableByteChannel mOutputChannel;
private IOException mSinkException;
private volatile boolean mStarted;
private volatile boolean mCanceled;
private volatile boolean mRecycled;
private volatile boolean mFinished;
private boolean mHeadersAvailable;
private String mContentType;
private long mContentLength;
private long mUploadContentLength;
+ private ConditionVariable mAppendChunkCondition;
private final ContextLock mLock;
/**
* Native adapter object, owned by UrlRequest.
*/
private long mUrlRequestAdapter;
@@ -106,14 +108,15 @@ public class UrlRequest {
*/
public void setUploadData(String contentType, byte[] data) {
synchronized (mLock) {
validateNotStarted();
mUploadContentType = contentType;
mUploadData = data;
mUploadChannel = null;
+ mAppendChunkCondition = null;
}
}
/**
* Sets a readable byte channel to upload as part of a POST request.
*
* @param contentType MIME type of the post content or null if this is not a
@@ -126,17 +129,72 @@ public class UrlRequest {
ReadableByteChannel channel, long contentLength) {
synchronized (mLock) {
validateNotStarted();
mUploadContentType = contentType;
mUploadChannel = channel;
mUploadContentLength = contentLength;
mUploadData = null;
+ mAppendChunkCondition = null;
+ }
+ }
+
+ /**
+ * Sets this request up for chunked uploading. To upload data call
+ * {@link #appendChunkBlocking(ByteBuffer, boolean)} after {@link #start()}.
+ *
+ * @param contentType MIME type of the post content or null if this is not a
+ * POST request.
+ */
+ public void setChunkedUpload(String contentType) {
+ synchronized (mLock) {
+ validateNotStarted();
+ mUploadContentType = contentType;
+ mAppendChunkCondition = new ConditionVariable();
+ mUploadData = null;
+ mUploadChannel = null;
}
}
+ /**
+ * Uploads a new chunk. Must have called {@link #setChunkedUpload(String)}
+ * and {@link #start()}.
+ *
+ * @param chunk The data, which will not be modified. It must not be empty
+ * and its current position must be zero.
+ * @param isLastChunk Whether this chunk is the last one.
+ */
+ public void appendChunkBlocking(ByteBuffer chunk, boolean isLastChunk)
+ throws IOException {
+ if (!chunk.hasRemaining()) {
+ throw new IllegalArgumentException(
+ "Attempted to write empty buffer.");
+ }
+ if (chunk.position() != 0) {
+ throw new IllegalArgumentException("The position must be zero.");
+ }
+ synchronized (mLock) {
+ if (!mStarted) {
+ throw new IllegalStateException("Request not yet started.");
+ }
+ if (mAppendChunkCondition == null) {
+ throw new IllegalStateException(
+ "Request not set for chunked uploadind.");
+ }
+ if (mUrlRequestAdapter == 0) {
+ throw new IOException("Native peer destroyed.");
+ }
+ mAppendChunkCondition.close();
+ nativeAppendChunk(mUrlRequestAdapter, chunk, chunk.limit(),
+ isLastChunk);
+ }
+ // Wait for the data to be actually consumed. Outside mLock to avoid
+ // deadlock.
+ mAppendChunkCondition.block();
+ }
+
public void setHttpMethod(String method) {
validateNotStarted();
if (!("PUT".equals(method) || "POST".equals(method))) {
throw new IllegalArgumentException("Only PUT or POST are allowed.");
}
mMethod = method;
}
@@ -155,15 +213,15 @@ public class UrlRequest {
validateNotRecycled();
mStarted = true;
String method = mMethod;
if (method == null &&
((mUploadData != null && mUploadData.length > 0) ||
- mUploadChannel != null)) {
+ mUploadChannel != null || mAppendChunkCondition != null)) {
// Default to POST if there is data to upload but no method was
// specified.
method = "POST";
}
if (method != null) {
nativeSetMethod(mUrlRequestAdapter, method);
@@ -186,14 +244,17 @@ public class UrlRequest {
if (mUploadData != null && mUploadData.length > 0) {
nativeSetUploadData(mUrlRequestAdapter, mUploadContentType,
mUploadData);
} else if (mUploadChannel != null) {
nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType,
mUploadContentLength);
+ } else if (mAppendChunkCondition != null) {
+ nativeEnableChunkedUpload(mUrlRequestAdapter,
+ mUploadContentType);
}
nativeStart(mUrlRequestAdapter);
}
}
public void cancel() {
@@ -284,14 +345,22 @@ public class UrlRequest {
validateHeadersAvailable();
ResponseHeadersMap result = new ResponseHeadersMap();
nativeGetAllHeaders(mUrlRequestAdapter, result);
return result;
}
/**
+ * A callback invoked when appending a chunk to the request has completed.
+ */
+ @CalledByNative
+ protected void onAppendChunkCompleted() {
+ mAppendChunkCondition.open();
+ }
+
+ /**
* A callback invoked when the first chunk of the response has arrived.
*/
@CalledByNative
protected void onResponseStarted() {
mContentType = nativeGetContentType(mUrlRequestAdapter);
mContentLength = nativeGetContentLength(mUrlRequestAdapter);
mHeadersAvailable = true;
@@ -326,14 +395,17 @@ public class UrlRequest {
* Notifies the listener, releases native data structures.
*/
@SuppressWarnings("unused")
@CalledByNative
private void finish() {
synchronized (mLock) {
mFinished = true;
+ if (mAppendChunkCondition != null) {
+ mAppendChunkCondition.open();
+ }
if (mRecycled) {
return;
}
try {
mSink.close();
} catch (IOException e) {
@@ -421,14 +493,20 @@ public class UrlRequest {
private native void nativeSetUploadData(long urlRequestAdapter,
String contentType, byte[] content);
private native void nativeSetUploadChannel(long urlRequestAdapter,
String contentType, long contentLength);
+ private native void nativeEnableChunkedUpload(long urlRequestAdapter,
+ String contentType);
+
+ private native void nativeAppendChunk(long urlRequestAdapter,
+ ByteBuffer chunk, int chunkSize, boolean isLastChunk);
+
private native void nativeStart(long urlRequestAdapter);
private native void nativeCancel(long urlRequestAdapter);
private native void nativeDestroyRequestAdapter(long urlRequestAdapter);
private native int nativeGetErrorCode(long urlRequestAdapter);

Powered by Google App Engine
This is Rietveld 408576698