1d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/* 2d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project 3d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 4d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License"); 5d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * you may not use this file except in compliance with the License. 6d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * You may obtain a copy of the License at 7d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 8d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * http://www.apache.org/licenses/LICENSE-2.0 9d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 10d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software 11d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS, 12d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * See the License for the specific language governing permissions and 14d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * limitations under the License. 15d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 16d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 17d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupackage com.android.volley; 18d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 19cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport android.net.TrafficStats; 20cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport android.net.Uri; 21d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.Handler; 22d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.Looper; 23d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.SystemClock; 24cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport android.text.TextUtils; 25cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 26cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charltonimport com.android.volley.VolleyLog.MarkerLog; 27d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 28d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.io.UnsupportedEncodingException; 29d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.net.URLEncoder; 30d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Collections; 31d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Map; 32d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 33d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/** 34d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Base class for all network requests. 35d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 36d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param <T> The type of parsed response this request expects. 37d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 38d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupublic abstract class Request<T> implements Comparable<Request<T>> { 39d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 40e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 41e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Default encoding for POST or PUT parameters. See {@link #getParamsEncoding()}. 42e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 43e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private static final String DEFAULT_PARAMS_ENCODING = "UTF-8"; 44e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 45e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 46e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Supported request methods. 47e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 48e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public interface Method { 49e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int DEPRECATED_GET_OR_POST = -1; 50e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int GET = 0; 51e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int POST = 1; 52e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int PUT = 2; 53e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru int DELETE = 3; 54364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu int HEAD = 4; 55364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu int OPTIONS = 5; 56364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu int TRACE = 6; 57364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu int PATCH = 7; 58e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 59d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 60d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** An event log tracing the lifetime of this request; for debugging. */ 61d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null; 62d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 63364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu /** 64364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu * Request method of this request. Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS, 65364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu * TRACE, and PATCH. 66364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu */ 67e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private final int mMethod; 68e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 69d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** URL of this request. */ 70d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final String mUrl; 71d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 72cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton /** Default tag for {@link TrafficStats}. */ 73cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton private final int mDefaultTrafficStatsTag; 74cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 75d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Listener interface for errors. */ 76d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final Response.ErrorListener mErrorListener; 77d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 78d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Sequence number of this request, used to enforce FIFO ordering. */ 79d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private Integer mSequence; 80d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 81d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** The request queue this request is associated with. */ 82d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private RequestQueue mRequestQueue; 83d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 84d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Whether or not responses to this request should be cached. */ 85d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private boolean mShouldCache = true; 86d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 87d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Whether or not this request has been canceled. */ 88d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private boolean mCanceled = false; 89d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 90d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Whether or not a response has been delivered for this request yet. */ 91d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private boolean mResponseDelivered = false; 92d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 93d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // A cheap variant of request tracing used to dump slow requests. 94d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private long mRequestBirthTime = 0; 95d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 96d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** Threshold at which we should log the request (even when debug logging is not enabled). */ 97d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private static final long SLOW_REQUEST_THRESHOLD_MS = 3000; 98d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 99d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** The retry policy for this request. */ 100d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private RetryPolicy mRetryPolicy; 101d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 102d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 103d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * When a request can be retrieved from cache but must be refreshed from 104d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * the network, the cache entry will be stored here so that in the event of 105d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * a "Not Modified" response, we can be sure it hasn't been evicted from cache. 106d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 107d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private Cache.Entry mCacheEntry = null; 108d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 109d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** An opaque token tagging this request; used for bulk cancellation. */ 110d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private Object mTag; 111d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 112d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 113d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Creates a new request with the given URL and error listener. Note that 114d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * the normal response listener is not provided here as delivery of responses 115d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * is provided by subclasses, who have a better idea of how to deliver an 116d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * already-parsed response. 117e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 118e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #Request(int, String, com.android.volley.Response.ErrorListener)}. 119d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 120e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton @Deprecated 121d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Request(String url, Response.ErrorListener listener) { 122e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru this(Method.DEPRECATED_GET_OR_POST, url, listener); 123e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 124e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 125e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 126e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Creates a new request with the given method (one of the values from {@link Method}), 127e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * URL, and error listener. Note that the normal response listener is not provided here as 128e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * delivery of responses is provided by subclasses, who have a better idea of how to deliver 129e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * an already-parsed response. 130e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 131e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public Request(int method, String url, Response.ErrorListener listener) { 132e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru mMethod = method; 133d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mUrl = url; 134d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mErrorListener = listener; 135d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru setRetryPolicy(new DefaultRetryPolicy()); 136cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 1370ec9297ffdf80183d17ca61759ecc18eae9f8167kang mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url); 138d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 139d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 140d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 141e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Return the method for this request. Can be one of the values in {@link Method}. 142e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 143e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public int getMethod() { 144e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return mMethod; 145e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 146e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 147e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 148d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Set a tag on this request. Can be used to cancel all requests with this 149d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * tag by {@link RequestQueue#cancelAll(Object)}. 150e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * 151e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * @return This Request object to allow for chaining. 152d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 153e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton public Request<?> setTag(Object tag) { 154d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mTag = tag; 155e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton return this; 156d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 157d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 158d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 159d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns this request's tag. 160d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @see Request#setTag(Object) 161d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 162d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Object getTag() { 163d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mTag; 164d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 165d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 166d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 16782fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele * @return this request's {@link com.android.volley.Response.ErrorListener}. 16882fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele */ 16982fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele public Response.ErrorListener getErrorListener() { 17082fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele return mErrorListener; 17182fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele } 17282fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele 17382fb1b23e63fa109a91532ce3c0c6f3ea9b7bb88Shirish Kalele /** 174cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton * @return A tag for use with {@link TrafficStats#setThreadStatsTag(int)} 175cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton */ 176cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton public int getTrafficStatsTag() { 177cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton return mDefaultTrafficStatsTag; 178cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton } 179cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton 180cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton /** 1810ec9297ffdf80183d17ca61759ecc18eae9f8167kang * @return The hashcode of the URL's host component, or 0 if there is none. 1820ec9297ffdf80183d17ca61759ecc18eae9f8167kang */ 1830ec9297ffdf80183d17ca61759ecc18eae9f8167kang private static int findDefaultTrafficStatsTag(String url) { 1840ec9297ffdf80183d17ca61759ecc18eae9f8167kang if (!TextUtils.isEmpty(url)) { 1850ec9297ffdf80183d17ca61759ecc18eae9f8167kang Uri uri = Uri.parse(url); 1860ec9297ffdf80183d17ca61759ecc18eae9f8167kang if (uri != null) { 1870ec9297ffdf80183d17ca61759ecc18eae9f8167kang String host = uri.getHost(); 1880ec9297ffdf80183d17ca61759ecc18eae9f8167kang if (host != null) { 1890ec9297ffdf80183d17ca61759ecc18eae9f8167kang return host.hashCode(); 1900ec9297ffdf80183d17ca61759ecc18eae9f8167kang } 1910ec9297ffdf80183d17ca61759ecc18eae9f8167kang } 1920ec9297ffdf80183d17ca61759ecc18eae9f8167kang } 1930ec9297ffdf80183d17ca61759ecc18eae9f8167kang return 0; 1940ec9297ffdf80183d17ca61759ecc18eae9f8167kang } 1950ec9297ffdf80183d17ca61759ecc18eae9f8167kang 1960ec9297ffdf80183d17ca61759ecc18eae9f8167kang /** 197d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Sets the retry policy for this request. 198e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * 199e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * @return This Request object to allow for chaining. 200d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 201e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton public Request<?> setRetryPolicy(RetryPolicy retryPolicy) { 202d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRetryPolicy = retryPolicy; 203e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton return this; 204d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 205d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 206d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 207d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Adds an event to this request's event log; for debugging. 208d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 209d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void addMarker(String tag) { 210d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (MarkerLog.ENABLED) { 211d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.add(tag, Thread.currentThread().getId()); 212d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } else if (mRequestBirthTime == 0) { 213d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRequestBirthTime = SystemClock.elapsedRealtime(); 214d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 215d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 216d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 217d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 218d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Notifies the request queue that this request has finished (successfully or with error). 219d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 220d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>Also dumps all events from this request's event log; for debugging.</p> 221d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 222d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru void finish(final String tag) { 223d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mRequestQueue != null) { 224d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRequestQueue.finish(this); 225d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 226d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (MarkerLog.ENABLED) { 227d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru final long threadId = Thread.currentThread().getId(); 228d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (Looper.myLooper() != Looper.getMainLooper()) { 229d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // If we finish marking off of the main thread, we need to 230d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // actually do it on the main thread to ensure correct ordering. 231d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Handler mainThread = new Handler(Looper.getMainLooper()); 232d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mainThread.post(new Runnable() { 233d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 234d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void run() { 235d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.add(tag, threadId); 236d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.finish(this.toString()); 237d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 238d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru }); 239d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return; 240d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 241d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 242d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.add(tag, threadId); 243d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mEventLog.finish(this.toString()); 244d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } else { 245d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime; 246d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) { 247d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru VolleyLog.d("%d ms: %s", requestTime, this.toString()); 248d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 249d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 250d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 251d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 252d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 253d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Associates this request with the given queue. The request queue will be notified when this 254d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * request has finished. 255e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * 256e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * @return This Request object to allow for chaining. 257d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 258e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton public Request<?> setRequestQueue(RequestQueue requestQueue) { 259d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mRequestQueue = requestQueue; 260e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton return this; 261d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 262d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 263d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 264d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Sets the sequence number of this request. Used by {@link RequestQueue}. 265e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * 266e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * @return This Request object to allow for chaining. 267d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 268e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton public final Request<?> setSequence(int sequence) { 269d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mSequence = sequence; 270e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton return this; 271d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 272d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 273d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 274d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the sequence number of this request. 275d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 276d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final int getSequence() { 277d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mSequence == null) { 278d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru throw new IllegalStateException("getSequence called before setSequence"); 279d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 280d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mSequence; 281d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 282d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 283d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 284d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the URL of this request. 285d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 286d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String getUrl() { 287d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mUrl; 288d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 289d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 290d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 291d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the cache key for this request. By default, this is the URL. 292d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 293d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String getCacheKey() { 294d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return getUrl(); 295d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 296d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 297d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 298d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Annotates this request with an entry retrieved for it from cache. 299d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Used for cache coherency support. 300e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * 301e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * @return This Request object to allow for chaining. 302d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 303e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton public Request<?> setCacheEntry(Cache.Entry entry) { 304d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mCacheEntry = entry; 305e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton return this; 306d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 307d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 308d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 309d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the annotated cache entry, or null if there isn't one. 310d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 311d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Cache.Entry getCacheEntry() { 312d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mCacheEntry; 313d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 314d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 315d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 316d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Mark this request as canceled. No callback will be delivered. 317d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 318d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void cancel() { 319d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mCanceled = true; 320d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 321d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 322d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 323d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns true if this request has been canceled. 324d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 325d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public boolean isCanceled() { 326d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mCanceled; 327d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 328d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 329d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 330d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns a list of extra HTTP headers to go along with this request. Can 331d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * throw {@link AuthFailureError} as authentication may be required to 332d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * provide these values. 333d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws AuthFailureError In the event of auth failure 334d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 335d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Map<String, String> getHeaders() throws AuthFailureError { 336d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return Collections.emptyMap(); 337d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 338d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 339d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 340d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns a Map of POST parameters to be used for this request, or null if 341d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * a simple GET should be used. Can throw {@link AuthFailureError} as 342d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * authentication may be required to provide these values. 343d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 344d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>Note that only one of getPostParams() and getPostBody() can return a non-null 345d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * value.</p> 346d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws AuthFailureError In the event of auth failure 347e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 348e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getParams()} instead. 349d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 350e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton @Deprecated 351d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected Map<String, String> getPostParams() throws AuthFailureError { 352e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return getParams(); 353d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 354d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 355d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 356d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns which encoding should be used when converting POST parameters returned by 357d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * {@link #getPostParams()} into a raw POST body. 358d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 359d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>This controls both encodings: 360d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <ol> 361d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <li>The string encoding used when converting parameter names and values into bytes prior 362d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * to URL encoding them.</li> 363d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <li>The string encoding used when converting the URL encoded parameters into a raw 364d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * byte array.</li> 365d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * </ol> 366e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 367e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getParamsEncoding()} instead. 368d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 369e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton @Deprecated 370d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected String getPostParamsEncoding() { 371e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return getParamsEncoding(); 372d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 373d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 374e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 375e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getBodyContentType()} instead. 376e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 377e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton @Deprecated 378d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String getPostBodyContentType() { 379e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return getBodyContentType(); 380d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 381d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 382d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 383d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the raw POST body to be sent. 384d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 385d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws AuthFailureError In the event of auth failure 386e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 387e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @deprecated Use {@link #getBody()} instead. 388d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 389e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton @Deprecated 390d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public byte[] getPostBody() throws AuthFailureError { 391e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // Note: For compatibility with legacy clients of volley, this implementation must remain 392e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // here instead of simply calling the getBody() function because this function must 393e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // call getPostParams() and getPostParamsEncoding() since legacy clients would have 394e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // overridden these two member functions for POST requests. 395d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Map<String, String> postParams = getPostParams(); 396d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (postParams != null && postParams.size() > 0) { 397e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return encodeParameters(postParams, getPostParamsEncoding()); 398e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 399e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return null; 400e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 401e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 402e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 403e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Returns a Map of parameters to be used for a POST or PUT request. Can throw 404e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * {@link AuthFailureError} as authentication may be required to provide these values. 405e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 406e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <p>Note that you can directly override {@link #getBody()} for custom data.</p> 407e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 408e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @throws AuthFailureError in the event of auth failure 409e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 410e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru protected Map<String, String> getParams() throws AuthFailureError { 411e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return null; 412e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 413e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 414e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 415e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Returns which encoding should be used when converting POST or PUT parameters returned by 416e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * {@link #getParams()} into a raw POST or PUT body. 417e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 418e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <p>This controls both encodings: 419e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <ol> 420e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <li>The string encoding used when converting parameter names and values into bytes prior 421e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * to URL encoding them.</li> 422e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * <li>The string encoding used when converting the URL encoded parameters into a raw 423e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * byte array.</li> 424e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * </ol> 425e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 426e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru protected String getParamsEncoding() { 427e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return DEFAULT_PARAMS_ENCODING; 428e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 429e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 430ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson /** 431ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson * Returns the content type of the POST or PUT body. 432ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson */ 433e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public String getBodyContentType() { 434e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return "application/x-www-form-urlencoded; charset=" + getParamsEncoding(); 435e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 436e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 437e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /** 438e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Returns the raw POST or PUT body to be sent. 439e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * 440ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson * <p>By default, the body consists of the request parameters in 441ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson * application/x-www-form-urlencoded format. When overriding this method, consider overriding 442ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson * {@link #getBodyContentType()} as well to match the new body format. 443ca7580d8ffae6d53500397d920570e77008f15fbJeff Davidson * 444e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * @throws AuthFailureError in the event of auth failure 445e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru */ 446e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru public byte[] getBody() throws AuthFailureError { 447e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru Map<String, String> params = getParams(); 448e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru if (params != null && params.size() > 0) { 449e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return encodeParameters(params, getParamsEncoding()); 450d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 451d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return null; 452d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 453d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 454d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 455e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru * Converts <code>params</code> into an application/x-www-form-urlencoded encoded string. 456d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 457e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) { 458d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru StringBuilder encodedParams = new StringBuilder(); 459d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru try { 460e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru for (Map.Entry<String, String> entry : params.entrySet()) { 461e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding)); 462d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru encodedParams.append('='); 463e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding)); 464d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru encodedParams.append('&'); 465d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 466e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru return encodedParams.toString().getBytes(paramsEncoding); 467d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } catch (UnsupportedEncodingException uee) { 468e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee); 469d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 470d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 471d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 472d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 473d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Set whether or not responses to this request should be cached. 474e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * 475e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton * @return This Request object to allow for chaining. 476d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 477e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton public final Request<?> setShouldCache(boolean shouldCache) { 478d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mShouldCache = shouldCache; 479e3280b4e47cf6fcc6b4e132baecbd15d7d6f8c19Evan Charlton return this; 480d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 481d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 482d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 483d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns true if responses to this request should be cached. 484d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 485d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final boolean shouldCache() { 486d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mShouldCache; 487d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 488d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 489d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 490d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Priority values. Requests will be processed from higher priorities to 491d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * lower priorities, in FIFO order. 492d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 493d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public enum Priority { 494d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru LOW, 495d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru NORMAL, 496d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru HIGH, 497d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru IMMEDIATE 498d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 499d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 500d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 501d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default. 502d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 503d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public Priority getPriority() { 504d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return Priority.NORMAL; 505d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 506d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 507d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 508d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the socket timeout in milliseconds per retry attempt. (This value can be changed 509d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * per retry attempt if a backoff is specified via backoffTimeout()). If there are no retry 510d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * attempts remaining, this will cause delivery of a {@link TimeoutError} error. 511d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 512d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public final int getTimeoutMs() { 513d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mRetryPolicy.getCurrentTimeout(); 514d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 515d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 516d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 517d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns the retry policy that should be used for this request. 518d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 519d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public RetryPolicy getRetryPolicy() { 520d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mRetryPolicy; 521d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 522d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 523d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 524d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Mark this request as having a response delivered on it. This can be used 525d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * later in the request's lifetime for suppressing identical responses. 526d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 527d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void markDelivered() { 528d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mResponseDelivered = true; 529d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 530d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 531d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 532d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns true if this request has had a response delivered for it. 533d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 534d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public boolean hasHadResponseDelivered() { 535d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return mResponseDelivered; 536d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 537d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 538d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 539d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Subclasses must implement this to parse the raw network response 540d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * and return an appropriate response type. This method will be 541d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * called from a worker thread. The response will not be delivered 542d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * if you return null. 543d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param response Response from the network 544d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @return The parsed response, or null in the case of an error 545d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 546d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru abstract protected Response<T> parseNetworkResponse(NetworkResponse response); 547d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 548d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 549d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Subclasses can override this method to parse 'networkError' and return a more specific error. 550d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 551d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * <p>The default implementation just returns the passed 'networkError'.</p> 552d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 553d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param volleyError the error retrieved from the network 554d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @return an NetworkError augmented with additional information 555d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 556d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected VolleyError parseNetworkError(VolleyError volleyError) { 557d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return volleyError; 558d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 559d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 560d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 561d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Subclasses must implement this to perform delivery of the parsed 562d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * response to their listeners. The given response is guaranteed to 563d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * be non-null; responses that fail to parse are not delivered. 564d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param response The parsed response returned by 565d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * {@link #parseNetworkResponse(NetworkResponse)} 566d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 567d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru abstract protected void deliverResponse(T response); 568d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 569d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 570d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Delivers error message to the ErrorListener that the Request was 571d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * initialized with. 572d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 573d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param error Error details 574d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 575d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void deliverError(VolleyError error) { 576d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mErrorListener != null) { 577d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mErrorListener.onErrorResponse(error); 578d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 579d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 580d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 581d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 582d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Our comparator sorts from high to low priority, and secondarily by 583d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * sequence number to provide FIFO ordering. 584d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 585d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 586d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public int compareTo(Request<T> other) { 587d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Priority left = this.getPriority(); 588d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Priority right = other.getPriority(); 589d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 590d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // High-priority requests are "lesser" so they are sorted to the front. 591d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Equal priorities are sorted by sequence number to provide FIFO ordering. 592d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return left == right ? 593d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru this.mSequence - other.mSequence : 594d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru right.ordinal() - left.ordinal(); 595d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 596d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 597d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 598d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String toString() { 599cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton String trafficStatsTag = "0x" + Integer.toHexString(getTrafficStatsTag()); 600cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton return (mCanceled ? "[X] " : "[ ] ") + getUrl() + " " + trafficStatsTag + " " 601cc3a9344202b3b3ee7e1a33b79591b3d11182354Evan Charlton + getPriority() + " " + mSequence; 602d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 603d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru} 604