1b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick/* 2b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * Copyright (C) 2011 The Android Open Source Project 3b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 4b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 5b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * you may not use this file except in compliance with the License. 6b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * You may obtain a copy of the License at 7b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 8b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * http://www.apache.org/licenses/LICENSE-2.0 9b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 10b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * Unless required by applicable law or agreed to in writing, software 11b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * distributed under the License is distributed on an "AS IS" BASIS, 12b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * See the License for the specific language governing permissions and 14b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * limitations under the License. 15b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick */ 16b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 17b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickpackage com.android.volley.toolbox; 18b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 19b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport com.android.volley.Request; 20b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport com.android.volley.Response; 21b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport com.android.volley.VolleyError; 22b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 23b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport java.util.concurrent.ExecutionException; 24b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport java.util.concurrent.Future; 25b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport java.util.concurrent.TimeUnit; 26b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickimport java.util.concurrent.TimeoutException; 27b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 28b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick/** 29b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * A Future that represents a Volley request. 30b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 31b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * Used by providing as your response and error listeners. For example: 32b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * <pre> 33b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * RequestFuture<JSONObject> future = RequestFuture.newFuture(); 34b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * MyRequest request = new MyRequest(URL, future, future); 35b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 36b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * // If you want to be able to cancel the request: 37b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * future.setRequest(requestQueue.add(request)); 38b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 39b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * // Otherwise: 40b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * requestQueue.add(request); 41b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 42b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * try { 43b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * JSONObject response = future.get(); 44b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * // do something with response 45b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * } catch (InterruptedException e) { 46b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * // handle the error 47b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * } catch (ExecutionException e) { 48b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * // handle the error 49b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * } 50b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * </pre> 51b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * 52b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick * @param <T> The type of parsed response this future expects. 53b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick */ 54b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrickpublic class RequestFuture<T> implements Future<T>, Response.Listener<T>, 55b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick Response.ErrorListener { 56b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick private Request<?> mRequest; 57b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick private boolean mResultReceived = false; 58b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick private T mResult; 59b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick private VolleyError mException; 60b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 61b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public static <E> RequestFuture<E> newFuture() { 62b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return new RequestFuture<E>(); 63b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 64b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 65b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick private RequestFuture() {} 66b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 67b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public void setRequest(Request<?> request) { 68b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick mRequest = request; 69b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 70b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 71b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 72b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public synchronized boolean cancel(boolean mayInterruptIfRunning) { 73b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (mRequest == null) { 74b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return false; 75b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 76b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 77b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (!isDone()) { 78b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick mRequest.cancel(); 79b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return true; 80b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } else { 81b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return false; 82b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 83b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 84b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 85b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 86b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public T get() throws InterruptedException, ExecutionException { 87b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick try { 88b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return doGet(null); 89b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } catch (TimeoutException e) { 90b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick throw new AssertionError(e); 91b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 92b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 93b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 94b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 95b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public T get(long timeout, TimeUnit unit) 96b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick throws InterruptedException, ExecutionException, TimeoutException { 97b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return doGet(TimeUnit.MILLISECONDS.convert(timeout, unit)); 98b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 99b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 100b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick private synchronized T doGet(Long timeoutMs) 101b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick throws InterruptedException, ExecutionException, TimeoutException { 102b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (mException != null) { 103b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick throw new ExecutionException(mException); 104b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 105b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 106b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (mResultReceived) { 107b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return mResult; 108b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 109b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 110b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (timeoutMs == null) { 111b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick wait(0); 112b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } else if (timeoutMs > 0) { 113b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick wait(timeoutMs); 114b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 115b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 116b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (mException != null) { 117b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick throw new ExecutionException(mException); 118b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 119b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 120b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (!mResultReceived) { 121b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick throw new TimeoutException(); 122b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 123b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 124b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return mResult; 125b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 126b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 127b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 128b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public boolean isCancelled() { 129b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick if (mRequest == null) { 130b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return false; 131b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 132b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return mRequest.isCanceled(); 133b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 134b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 135b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 136b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public synchronized boolean isDone() { 137b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick return mResultReceived || mException != null || isCancelled(); 138b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 139b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 140b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 141b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public synchronized void onResponse(T response) { 142b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick mResultReceived = true; 143b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick mResult = response; 144b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick notifyAll(); 145b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 146b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 147b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick @Override 148b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick public synchronized void onErrorResponse(VolleyError error) { 149b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick mException = error; 150b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick notifyAll(); 151b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick } 152b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick} 153b5f1a5083f4d6a0e4ca8403243b37ea2609bcf39Ficus Kirkpatrick 154