diff options
Diffstat (limited to 'src/main/java/com/android/volley/Request.java')
-rw-r--r-- | src/main/java/com/android/volley/Request.java | 719 |
1 files changed, 0 insertions, 719 deletions
diff --git a/src/main/java/com/android/volley/Request.java b/src/main/java/com/android/volley/Request.java deleted file mode 100644 index b60dc74..0000000 --- a/src/main/java/com/android/volley/Request.java +++ /dev/null @@ -1,719 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.volley; - -import android.net.TrafficStats; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.text.TextUtils; -import androidx.annotation.CallSuper; -import androidx.annotation.GuardedBy; -import androidx.annotation.Nullable; -import com.android.volley.VolleyLog.MarkerLog; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.Collections; -import java.util.Map; - -/** - * Base class for all network requests. - * - * @param <T> The type of parsed response this request expects. - */ -public abstract class Request<T> implements Comparable<Request<T>> { - - /** Default encoding for POST or PUT parameters. See {@link #getParamsEncoding()}. */ - private static final String DEFAULT_PARAMS_ENCODING = "UTF-8"; - - /** Supported request methods. */ - public interface Method { - int DEPRECATED_GET_OR_POST = -1; - int GET = 0; - int POST = 1; - int PUT = 2; - int DELETE = 3; - int HEAD = 4; - int OPTIONS = 5; - int TRACE = 6; - int PATCH = 7; - } - - /** Callback to notify when the network request returns. */ - /* package */ interface NetworkRequestCompleteListener { - - /** Callback when a network response has been received. */ - void onResponseReceived(Request<?> request, Response<?> response); - - /** Callback when request returns from network without valid response. */ - void onNoUsableResponseReceived(Request<?> request); - } - - /** An event log tracing the lifetime of this request; for debugging. */ - private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null; - - /** - * Request method of this request. Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS, - * TRACE, and PATCH. - */ - private final int mMethod; - - /** URL of this request. */ - private final String mUrl; - - /** Default tag for {@link TrafficStats}. */ - private final int mDefaultTrafficStatsTag; - - /** Lock to guard state which can be mutated after a request is added to the queue. */ - private final Object mLock = new Object(); - - /** Listener interface for errors. */ - @Nullable - @GuardedBy("mLock") - private Response.ErrorListener mErrorListener; - - /** Sequence number of this request, used to enforce FIFO ordering. */ - private Integer mSequence; - - /** The request queue this request is associated with. */ - private RequestQueue mRequestQueue; - - /** Whether or not responses to this request should be cached. */ - // TODO(#190): Turn this off by default for anything other than GET requests. - private boolean mShouldCache = true; - - /** Whether or not this request has been canceled. */ - @GuardedBy("mLock") - private boolean mCanceled = false; - - /** Whether or not a response has been delivered for this request yet. */ - @GuardedBy("mLock") - private boolean mResponseDelivered = false; - - /** Whether the request should be retried in the event of an HTTP 5xx (server) error. */ - private boolean mShouldRetryServerErrors = false; - - /** Whether the request should be retried in the event of a {@link NoConnectionError}. */ - private boolean mShouldRetryConnectionErrors = false; - - /** The retry policy for this request. */ - private RetryPolicy mRetryPolicy; - - /** - * When a request can be retrieved from cache but must be refreshed from the network, the cache - * entry will be stored here so that in the event of a "Not Modified" response, we can be sure - * it hasn't been evicted from cache. - */ - @Nullable private Cache.Entry mCacheEntry = null; - - /** An opaque token tagging this request; used for bulk cancellation. */ - private Object mTag; - - /** Listener that will be notified when a response has been delivered. */ - @GuardedBy("mLock") - private NetworkRequestCompleteListener mRequestCompleteListener; - - /** - * Creates a new request with the given URL and error listener. Note that the normal response - * listener is not provided here as delivery of responses is provided by subclasses, who have a - * better idea of how to deliver an already-parsed response. - * - * @deprecated Use {@link #Request(int, String, com.android.volley.Response.ErrorListener)}. - */ - @Deprecated - public Request(String url, Response.ErrorListener listener) { - this(Method.DEPRECATED_GET_OR_POST, url, listener); - } - - /** - * Creates a new request with the given method (one of the values from {@link Method}), URL, and - * error listener. Note that the normal response listener is not provided here as delivery of - * responses is provided by subclasses, who have a better idea of how to deliver an - * already-parsed response. - */ - public Request(int method, String url, @Nullable Response.ErrorListener listener) { - mMethod = method; - mUrl = url; - mErrorListener = listener; - setRetryPolicy(new DefaultRetryPolicy()); - - mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url); - } - - /** Return the method for this request. Can be one of the values in {@link Method}. */ - public int getMethod() { - return mMethod; - } - - /** - * Set a tag on this request. Can be used to cancel all requests with this tag by {@link - * RequestQueue#cancelAll(Object)}. - * - * @return This Request object to allow for chaining. - */ - public Request<?> setTag(Object tag) { - mTag = tag; - return this; - } - - /** - * Returns this request's tag. - * - * @see Request#setTag(Object) - */ - public Object getTag() { - return mTag; - } - - /** @return this request's {@link com.android.volley.Response.ErrorListener}. */ - @Nullable - public Response.ErrorListener getErrorListener() { - synchronized (mLock) { - return mErrorListener; - } - } - - /** @return A tag for use with {@link TrafficStats#setThreadStatsTag(int)} */ - public int getTrafficStatsTag() { - return mDefaultTrafficStatsTag; - } - - /** @return The hashcode of the URL's host component, or 0 if there is none. */ - private static int findDefaultTrafficStatsTag(String url) { - if (!TextUtils.isEmpty(url)) { - Uri uri = Uri.parse(url); - if (uri != null) { - String host = uri.getHost(); - if (host != null) { - return host.hashCode(); - } - } - } - return 0; - } - - /** - * Sets the retry policy for this request. - * - * @return This Request object to allow for chaining. - */ - public Request<?> setRetryPolicy(RetryPolicy retryPolicy) { - mRetryPolicy = retryPolicy; - return this; - } - - /** Adds an event to this request's event log; for debugging. */ - public void addMarker(String tag) { - if (MarkerLog.ENABLED) { - mEventLog.add(tag, Thread.currentThread().getId()); - } - } - - /** - * Notifies the request queue that this request has finished (successfully or with error). - * - * <p>Also dumps all events from this request's event log; for debugging. - */ - void finish(final String tag) { - if (mRequestQueue != null) { - mRequestQueue.finish(this); - } - if (MarkerLog.ENABLED) { - final long threadId = Thread.currentThread().getId(); - if (Looper.myLooper() != Looper.getMainLooper()) { - // If we finish marking off of the main thread, we need to - // actually do it on the main thread to ensure correct ordering. - Handler mainThread = new Handler(Looper.getMainLooper()); - mainThread.post( - new Runnable() { - @Override - public void run() { - mEventLog.add(tag, threadId); - mEventLog.finish(Request.this.toString()); - } - }); - return; - } - - mEventLog.add(tag, threadId); - mEventLog.finish(this.toString()); - } - } - - void sendEvent(@RequestQueue.RequestEvent int event) { - if (mRequestQueue != null) { - mRequestQueue.sendRequestEvent(this, event); - } - } - - /** - * Associates this request with the given queue. The request queue will be notified when this - * request has finished. - * - * @return This Request object to allow for chaining. - */ - public Request<?> setRequestQueue(RequestQueue requestQueue) { - mRequestQueue = requestQueue; - return this; - } - - /** - * Sets the sequence number of this request. Used by {@link RequestQueue}. - * - * @return This Request object to allow for chaining. - */ - public final Request<?> setSequence(int sequence) { - mSequence = sequence; - return this; - } - - /** Returns the sequence number of this request. */ - public final int getSequence() { - if (mSequence == null) { - throw new IllegalStateException("getSequence called before setSequence"); - } - return mSequence; - } - - /** Returns the URL of this request. */ - public String getUrl() { - return mUrl; - } - - /** Returns the cache key for this request. By default, this is the URL. */ - public String getCacheKey() { - String url = getUrl(); - // If this is a GET request, just use the URL as the key. - // For callers using DEPRECATED_GET_OR_POST, we assume the method is GET, which matches - // legacy behavior where all methods had the same cache key. We can't determine which method - // will be used because doing so requires calling getPostBody() which is expensive and may - // throw AuthFailureError. - // TODO(#190): Remove support for non-GET methods. - int method = getMethod(); - if (method == Method.GET || method == Method.DEPRECATED_GET_OR_POST) { - return url; - } - return Integer.toString(method) + '-' + url; - } - - /** - * Annotates this request with an entry retrieved for it from cache. Used for cache coherency - * support. - * - * @return This Request object to allow for chaining. - */ - public Request<?> setCacheEntry(Cache.Entry entry) { - mCacheEntry = entry; - return this; - } - - /** Returns the annotated cache entry, or null if there isn't one. */ - @Nullable - public Cache.Entry getCacheEntry() { - return mCacheEntry; - } - - /** - * Mark this request as canceled. - * - * <p>No callback will be delivered as long as either: - * - * <ul> - * <li>This method is called on the same thread as the {@link ResponseDelivery} is running on. - * By default, this is the main thread. - * <li>The request subclass being used overrides cancel() and ensures that it does not invoke - * the listener in {@link #deliverResponse} after cancel() has been called in a - * thread-safe manner. - * </ul> - * - * <p>There are no guarantees if both of these conditions aren't met. - */ - @CallSuper - public void cancel() { - synchronized (mLock) { - mCanceled = true; - mErrorListener = null; - } - } - - /** Returns true if this request has been canceled. */ - public boolean isCanceled() { - synchronized (mLock) { - return mCanceled; - } - } - - /** - * Returns a list of extra HTTP headers to go along with this request. Can throw {@link - * AuthFailureError} as authentication may be required to provide these values. - * - * @throws AuthFailureError In the event of auth failure - */ - public Map<String, String> getHeaders() throws AuthFailureError { - return Collections.emptyMap(); - } - - /** - * Returns a Map of POST parameters to be used for this request, or null if a simple GET should - * be used. Can throw {@link AuthFailureError} as authentication may be required to provide - * these values. - * - * <p>Note that only one of getPostParams() and getPostBody() can return a non-null value. - * - * @throws AuthFailureError In the event of auth failure - * @deprecated Use {@link #getParams()} instead. - */ - @Deprecated - @Nullable - protected Map<String, String> getPostParams() throws AuthFailureError { - return getParams(); - } - - /** - * Returns which encoding should be used when converting POST parameters returned by {@link - * #getPostParams()} into a raw POST body. - * - * <p>This controls both encodings: - * - * <ol> - * <li>The string encoding used when converting parameter names and values into bytes prior to - * URL encoding them. - * <li>The string encoding used when converting the URL encoded parameters into a raw byte - * array. - * </ol> - * - * @deprecated Use {@link #getParamsEncoding()} instead. - */ - @Deprecated - protected String getPostParamsEncoding() { - return getParamsEncoding(); - } - - /** @deprecated Use {@link #getBodyContentType()} instead. */ - @Deprecated - public String getPostBodyContentType() { - return getBodyContentType(); - } - - /** - * Returns the raw POST body to be sent. - * - * @throws AuthFailureError In the event of auth failure - * @deprecated Use {@link #getBody()} instead. - */ - @Deprecated - public byte[] getPostBody() throws AuthFailureError { - // Note: For compatibility with legacy clients of volley, this implementation must remain - // here instead of simply calling the getBody() function because this function must - // call getPostParams() and getPostParamsEncoding() since legacy clients would have - // overridden these two member functions for POST requests. - Map<String, String> postParams = getPostParams(); - if (postParams != null && postParams.size() > 0) { - return encodeParameters(postParams, getPostParamsEncoding()); - } - return null; - } - - /** - * Returns a Map of parameters to be used for a POST or PUT request. Can throw {@link - * AuthFailureError} as authentication may be required to provide these values. - * - * <p>Note that you can directly override {@link #getBody()} for custom data. - * - * @throws AuthFailureError in the event of auth failure - */ - @Nullable - protected Map<String, String> getParams() throws AuthFailureError { - return null; - } - - /** - * Returns which encoding should be used when converting POST or PUT parameters returned by - * {@link #getParams()} into a raw POST or PUT body. - * - * <p>This controls both encodings: - * - * <ol> - * <li>The string encoding used when converting parameter names and values into bytes prior to - * URL encoding them. - * <li>The string encoding used when converting the URL encoded parameters into a raw byte - * array. - * </ol> - */ - protected String getParamsEncoding() { - return DEFAULT_PARAMS_ENCODING; - } - - /** Returns the content type of the POST or PUT body. */ - public String getBodyContentType() { - return "application/x-www-form-urlencoded; charset=" + getParamsEncoding(); - } - - /** - * Returns the raw POST or PUT body to be sent. - * - * <p>By default, the body consists of the request parameters in - * application/x-www-form-urlencoded format. When overriding this method, consider overriding - * {@link #getBodyContentType()} as well to match the new body format. - * - * @throws AuthFailureError in the event of auth failure - */ - public byte[] getBody() throws AuthFailureError { - Map<String, String> params = getParams(); - if (params != null && params.size() > 0) { - return encodeParameters(params, getParamsEncoding()); - } - return null; - } - - /** Converts <code>params</code> into an application/x-www-form-urlencoded encoded string. */ - private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) { - StringBuilder encodedParams = new StringBuilder(); - try { - for (Map.Entry<String, String> entry : params.entrySet()) { - if (entry.getKey() == null || entry.getValue() == null) { - throw new IllegalArgumentException( - String.format( - "Request#getParams() or Request#getPostParams() returned a map " - + "containing a null key or value: (%s, %s). All keys " - + "and values must be non-null.", - entry.getKey(), entry.getValue())); - } - encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding)); - encodedParams.append('='); - encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding)); - encodedParams.append('&'); - } - return encodedParams.toString().getBytes(paramsEncoding); - } catch (UnsupportedEncodingException uee) { - throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee); - } - } - - /** - * Set whether or not responses to this request should be cached. - * - * @return This Request object to allow for chaining. - */ - public final Request<?> setShouldCache(boolean shouldCache) { - mShouldCache = shouldCache; - return this; - } - - /** Returns true if responses to this request should be cached. */ - public final boolean shouldCache() { - return mShouldCache; - } - - /** - * Sets whether or not the request should be retried in the event of an HTTP 5xx (server) error. - * - * @return This Request object to allow for chaining. - */ - public final Request<?> setShouldRetryServerErrors(boolean shouldRetryServerErrors) { - mShouldRetryServerErrors = shouldRetryServerErrors; - return this; - } - - /** - * Returns true if this request should be retried in the event of an HTTP 5xx (server) error. - */ - public final boolean shouldRetryServerErrors() { - return mShouldRetryServerErrors; - } - - /** - * Sets whether or not the request should be retried in the event that no connection could be - * established. - * - * @return This Request object to allow for chaining. - */ - public final Request<?> setShouldRetryConnectionErrors(boolean shouldRetryConnectionErrors) { - mShouldRetryConnectionErrors = shouldRetryConnectionErrors; - return this; - } - - /** - * Returns true if this request should be retried in the event that no connection could be - * established. - */ - public final boolean shouldRetryConnectionErrors() { - return mShouldRetryConnectionErrors; - } - - /** - * Priority values. Requests will be processed from higher priorities to lower priorities, in - * FIFO order. - */ - public enum Priority { - LOW, - NORMAL, - HIGH, - IMMEDIATE - } - - /** Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default. */ - public Priority getPriority() { - return Priority.NORMAL; - } - - /** - * Returns the socket timeout in milliseconds per retry attempt. (This value can be changed per - * retry attempt if a backoff is specified via backoffTimeout()). If there are no retry attempts - * remaining, this will cause delivery of a {@link TimeoutError} error. - */ - public final int getTimeoutMs() { - return getRetryPolicy().getCurrentTimeout(); - } - - /** Returns the retry policy that should be used for this request. */ - public RetryPolicy getRetryPolicy() { - return mRetryPolicy; - } - - /** - * Mark this request as having a response delivered on it. This can be used later in the - * request's lifetime for suppressing identical responses. - */ - public void markDelivered() { - synchronized (mLock) { - mResponseDelivered = true; - } - } - - /** Returns true if this request has had a response delivered for it. */ - public boolean hasHadResponseDelivered() { - synchronized (mLock) { - return mResponseDelivered; - } - } - - /** - * Subclasses must implement this to parse the raw network response and return an appropriate - * response type. This method will be called from a worker thread. The response will not be - * delivered if you return null. - * - * @param response Response from the network - * @return The parsed response, or null in the case of an error - */ - protected abstract Response<T> parseNetworkResponse(NetworkResponse response); - - /** - * Subclasses can override this method to parse 'networkError' and return a more specific error. - * - * <p>The default implementation just returns the passed 'networkError'. - * - * @param volleyError the error retrieved from the network - * @return an NetworkError augmented with additional information - */ - protected VolleyError parseNetworkError(VolleyError volleyError) { - return volleyError; - } - - /** - * Subclasses must implement this to perform delivery of the parsed response to their listeners. - * The given response is guaranteed to be non-null; responses that fail to parse are not - * delivered. - * - * @param response The parsed response returned by {@link - * #parseNetworkResponse(NetworkResponse)} - */ - protected abstract void deliverResponse(T response); - - /** - * Delivers error message to the ErrorListener that the Request was initialized with. - * - * @param error Error details - */ - public void deliverError(VolleyError error) { - Response.ErrorListener listener; - synchronized (mLock) { - listener = mErrorListener; - } - if (listener != null) { - listener.onErrorResponse(error); - } - } - - /** - * {@link NetworkRequestCompleteListener} that will receive callbacks when the request returns - * from the network. - */ - /* package */ void setNetworkRequestCompleteListener( - NetworkRequestCompleteListener requestCompleteListener) { - synchronized (mLock) { - mRequestCompleteListener = requestCompleteListener; - } - } - - /** - * Notify NetworkRequestCompleteListener that a valid response has been received which can be - * used for other, waiting requests. - * - * @param response received from the network - */ - /* package */ void notifyListenerResponseReceived(Response<?> response) { - NetworkRequestCompleteListener listener; - synchronized (mLock) { - listener = mRequestCompleteListener; - } - if (listener != null) { - listener.onResponseReceived(this, response); - } - } - - /** - * Notify NetworkRequestCompleteListener that the network request did not result in a response - * which can be used for other, waiting requests. - */ - /* package */ void notifyListenerResponseNotUsable() { - NetworkRequestCompleteListener listener; - synchronized (mLock) { - listener = mRequestCompleteListener; - } - if (listener != null) { - listener.onNoUsableResponseReceived(this); - } - } - - /** - * Our comparator sorts from high to low priority, and secondarily by sequence number to provide - * FIFO ordering. - */ - @Override - public int compareTo(Request<T> other) { - Priority left = this.getPriority(); - Priority right = other.getPriority(); - - // High-priority requests are "lesser" so they are sorted to the front. - // Equal priorities are sorted by sequence number to provide FIFO ordering. - return left == right ? this.mSequence - other.mSequence : right.ordinal() - left.ordinal(); - } - - @Override - public String toString() { - String trafficStatsTag = "0x" + Integer.toHexString(getTrafficStatsTag()); - return (isCanceled() ? "[X] " : "[ ] ") - + getUrl() - + " " - + trafficStatsTag - + " " - + getPriority() - + " " - + mSequence; - } -} |