13713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick/* 23713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Copyright (C) 2011 The Android Open Source Project 33713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * 43713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 53713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * you may not use this file except in compliance with the License. 63713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * You may obtain a copy of the License at 73713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * 83713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * http://www.apache.org/licenses/LICENSE-2.0 93713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * 103713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Unless required by applicable law or agreed to in writing, software 113713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * distributed under the License is distributed on an "AS IS" BASIS, 123713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * See the License for the specific language governing permissions and 143713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * limitations under the License. 153713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 163713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 173713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickpackage com.android.volley; 183713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 193713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport android.os.Handler; 203713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 213713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.util.concurrent.Executor; 223713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 233713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick/** 243713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Delivers responses and errors. 253713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 263713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickpublic class ExecutorDelivery implements ResponseDelivery { 273713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** Used for posting responses, typically to the main thread. */ 283713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private final Executor mResponsePoster; 293713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 303713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** Requests with a sequence number below this one will have responses dropped. */ 313713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private int mDiscardBefore = 0; 323713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 333713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 343713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Creates a new response delivery interface. 353713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * @param handler {@link Handler} to post responses on 363713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 373713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public ExecutorDelivery(final Handler handler) { 383713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // Make an Executor that just wraps the handler. 393713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mResponsePoster = new Executor() { 403713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 413713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public void execute(Runnable command) { 423713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick handler.post(command); 433713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 443713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick }; 453713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 463713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 473713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 483713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Creates a new response delivery interface, mockable version 493713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * for testing. 503713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * @param executor For running delivery tasks 513713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 523713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public ExecutorDelivery(Executor executor) { 533713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mResponsePoster = executor; 543713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 553713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 563713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 573713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public void postResponse(Request<?> request, Response<?> response) { 583713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick postResponse(request, response, null); 593713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 603713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 613713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 623713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public void postResponse(Request<?> request, Response<?> response, Runnable runnable) { 633713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request.markDelivered(); 643713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request.addMarker("post-response"); 653713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable)); 663713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 673713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 683713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 693713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public void postError(Request<?> request, VolleyError error) { 703713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request.addMarker("post-error"); 713713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick Response<?> response = Response.error(error); 723713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null)); 733713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 743713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 753713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 763713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public void discardBefore(int sequence) { 773713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mDiscardBefore = sequence; 783713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 793713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 803713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 813713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * A Runnable used for delivering network responses to a listener on the 823713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * main thread. 833713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 843713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @SuppressWarnings("rawtypes") 853713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private class ResponseDeliveryRunnable implements Runnable { 863713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private final Request mRequest; 873713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private final Response mResponse; 883713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private final Runnable mRunnable; 893713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 903713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) { 913713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRequest = request; 923713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mResponse = response; 933713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRunnable = runnable; 943713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 953713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 963713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @SuppressWarnings("unchecked") 973713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 983713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public void run() { 993713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // Don't deliver the response if this request was canceled during processing 1003713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // or if discardBefore() has been called with a sequence number greater than 1013713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // or equal to this request's sequence number. 1023713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick boolean drained = mRequest.isDrainable() && 1033713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick (mRequest.getSequence() < mDiscardBefore); 1043713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1053713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // If this request has been drained or canceled, finish it and don't deliver. 1063713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (drained || mRequest.isCanceled()) { 1073713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRequest.finish("canceled-at-delivery"); 1083713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick return; 1093713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1103713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1113713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // Deliver a normal response or error, depending. 1123713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (mResponse.isSuccess()) { 1133713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRequest.deliverResponse(mResponse.result); 1143713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } else { 1153713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRequest.deliverError(mResponse.error); 1163713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1173713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1183713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // If this is an intermediate response, add a marker, otherwise we're done 1193713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // and the request can be finished. 1203713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (mResponse.intermediate) { 1213713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRequest.addMarker("intermediate-response"); 1223713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } else { 1233713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRequest.finish("done"); 1243713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1253713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1263713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // If we have been provided a post-delivery runnable, run it. 1273713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (mRunnable != null) { 1283713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mRunnable.run(); 1293713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1303713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1313713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1323713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick} 133