• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.volley;
18 
19 import android.os.Handler;
20 
21 import java.util.concurrent.Executor;
22 
23 /**
24  * Delivers responses and errors.
25  */
26 public class ExecutorDelivery implements ResponseDelivery {
27     /** Used for posting responses, typically to the main thread. */
28     private final Executor mResponsePoster;
29 
30     /** Requests with a sequence number below this one will have responses dropped. */
31     private int mDiscardBefore = 0;
32 
33     /**
34      * Creates a new response delivery interface.
35      * @param handler {@link Handler} to post responses on
36      */
ExecutorDelivery(final Handler handler)37     public ExecutorDelivery(final Handler handler) {
38         // Make an Executor that just wraps the handler.
39         mResponsePoster = new Executor() {
40             @Override
41             public void execute(Runnable command) {
42                 handler.post(command);
43             }
44         };
45     }
46 
47     /**
48      * Creates a new response delivery interface, mockable version
49      * for testing.
50      * @param executor For running delivery tasks
51      */
ExecutorDelivery(Executor executor)52     public ExecutorDelivery(Executor executor) {
53         mResponsePoster = executor;
54     }
55 
56     @Override
postResponse(Request<?> request, Response<?> response)57     public void postResponse(Request<?> request, Response<?> response) {
58         postResponse(request, response, null);
59     }
60 
61     @Override
postResponse(Request<?> request, Response<?> response, Runnable runnable)62     public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
63         request.markDelivered();
64         request.addMarker("post-response");
65         mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
66     }
67 
68     @Override
postError(Request<?> request, VolleyError error)69     public void postError(Request<?> request, VolleyError error) {
70         request.addMarker("post-error");
71         Response<?> response = Response.error(error);
72         mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
73     }
74 
75     @Override
discardBefore(int sequence)76     public void discardBefore(int sequence) {
77         mDiscardBefore = sequence;
78     }
79 
80     /**
81      * A Runnable used for delivering network responses to a listener on the
82      * main thread.
83      */
84     @SuppressWarnings("rawtypes")
85     private class ResponseDeliveryRunnable implements Runnable {
86         private final Request mRequest;
87         private final Response mResponse;
88         private final Runnable mRunnable;
89 
ResponseDeliveryRunnable(Request request, Response response, Runnable runnable)90         public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
91             mRequest = request;
92             mResponse = response;
93             mRunnable = runnable;
94         }
95 
96         @SuppressWarnings("unchecked")
97         @Override
run()98         public void run() {
99             // Don't deliver the response if this request was canceled during processing
100             // or if discardBefore() has been called with a sequence number greater than
101             // or equal to this request's sequence number.
102             boolean drained = mRequest.isDrainable() &&
103                 (mRequest.getSequence() < mDiscardBefore);
104 
105             // If this request has been drained or canceled, finish it and don't deliver.
106             if (drained || mRequest.isCanceled()) {
107                 mRequest.finish("canceled-at-delivery");
108                 return;
109             }
110 
111             // Deliver a normal response or error, depending.
112             if (mResponse.isSuccess()) {
113                 mRequest.deliverResponse(mResponse.result);
114             } else {
115                 mRequest.deliverError(mResponse.error);
116             }
117 
118             // If this is an intermediate response, add a marker, otherwise we're done
119             // and the request can be finished.
120             if (mResponse.intermediate) {
121                 mRequest.addMarker("intermediate-response");
122             } else {
123                 mRequest.finish("done");
124             }
125 
126             // If we have been provided a post-delivery runnable, run it.
127             if (mRunnable != null) {
128                 mRunnable.run();
129             }
130        }
131     }
132 }
133