1a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom/*
2a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Copyright (C) 2011 The Android Open Source Project
3a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
4a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * you may not use this file except in compliance with the License.
6a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * You may obtain a copy of the License at
7a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
8a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
10a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
11a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * See the License for the specific language governing permissions and
14a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * limitations under the License.
15a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */
16a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
17a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrompackage android.net.http;
18a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
19a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport android.content.Context;
20a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.io.Closeable;
21a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.io.File;
22a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.io.IOException;
23a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.CacheRequest;
24a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.CacheResponse;
2518c227ba72406c0b69ce9925a80113060d870256Jesse Wilsonimport java.net.ExtendedResponseCache;
26a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.HttpURLConnection;
27a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.ResponseCache;
2818c227ba72406c0b69ce9925a80113060d870256Jesse Wilsonimport java.net.ResponseSource;
29a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.URI;
30a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.URLConnection;
31a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.util.List;
32a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.util.Map;
33a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport javax.net.ssl.HttpsURLConnection;
34a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport libcore.io.DiskLruCache;
35a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport libcore.io.IoUtils;
36a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport org.apache.http.impl.client.DefaultHttpClient;
37a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
38a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom/**
39a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Caches HTTP and HTTPS responses to the filesystem so they may be reused,
40a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * saving time and bandwidth. This class supports {@link HttpURLConnection} and
41a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * {@link HttpsURLConnection}; there is no platform-provided cache for {@link
42a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * DefaultHttpClient} or {@link AndroidHttpClient}.
43a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
44a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Installing an HTTP response cache</h3>
45a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Enable caching of all of your application's HTTP requests by installing the
46a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * cache at application startup. For example, this code installs a 10 MiB cache
47a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * in the {@link Context#getCacheDir() application-specific cache directory} of
48a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * the filesystem}: <pre>   {@code
49a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *   protected void onCreate(Bundle savedInstanceState) {
50a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       ...
51a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
52a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       try {
53a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *           File httpCacheDir = new File(context.getCacheDir(), "http");
54a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *           long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
55a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *           HttpResponseCache.install(httpCacheDir, httpCacheSize);
56a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       } catch (IOException e) {
57a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *           Log.i(TAG, "HTTP response cache installation failed:" + e);
58a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       }
59a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *   }
60a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
61a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *   protected void onStop() {
62a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       ...
63a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
64a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       HttpResponseCache cache = HttpResponseCache.getInstalled();
65a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       if (cache != null) {
66a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *           cache.flush();
67a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *       }
68a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *   }}</pre>
69a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * This cache will evict entries as necessary to keep its size from exceeding
70a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 10 MiB. The best cache size is application specific and depends on the size
71a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * and frequency of the files being downloaded. Increasing the limit may improve
72a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * the hit rate, but it may also just waste filesystem space!
73a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
74a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <p>For some applications it may be preferable to create the cache in the
7598e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * external storage directory. <strong>There are no access controls on the
7698e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * external storage directory so it should not be used for caches that could
7798e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * contain private data.</strong> Although it often has more free space,
7898e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * external storage is optional and&#8212;even if available&#8212;can disappear
7998e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * during use. Retrieve the external cache directory using {@link
8098e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * Context#getExternalCacheDir()}. If this method returns null, your application
8198e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * should fall back to either not caching or caching on non-external storage. If
8298e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * the external storage is removed during use, the cache hit rate will drop to
8398e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * zero and ongoing cache reads will fail.
84a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
85a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <p>Flushing the cache forces its data to the filesystem. This ensures that
86a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * all responses written to the cache will be readable the next time the
87a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * activity starts.
88a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
89a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Cache Optimization</h3>
90a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * To measure cache effectiveness, this class tracks three statistics:
91a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <ul>
92a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *     <li><strong>{@link #getRequestCount() Request Count:}</strong> the number
93a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         of HTTP requests issued since this cache was created.
94a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *     <li><strong>{@link #getNetworkCount() Network Count:}</strong> the
95a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         number of those requests that required network use.
96a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *     <li><strong>{@link #getHitCount() Hit Count:}</strong> the number of
97a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         those requests whose responses were served by the cache.
98a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * </ul>
99a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Sometimes a request will result in a conditional cache hit. If the cache
100a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * contains a stale copy of the response, the client will issue a conditional
101a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * {@code GET}. The server will then send either the updated response if it has
102a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * changed, or a short 'not modified' response if the client's copy is still
103a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * valid. Such responses increment both the network count and hit count.
104a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
105a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <p>The best way to improve the cache hit rate is by configuring the web
106a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * server to return cacheable responses. Although this client honors all <a
107a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * href="http://www.ietf.org/rfc/rfc2616.txt">HTTP/1.1 (RFC 2068)</a> cache
108a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * headers, it doesn't cache partial responses.
109a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
110a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Force a Network Response</h3>
111a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * In some situations, such as after a user clicks a 'refresh' button, it may be
112a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * necessary to skip the cache, and fetch data directly from the server. To force
113a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * a full refresh, add the {@code no-cache} directive: <pre>   {@code
114a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         connection.addRequestProperty("Cache-Control", "no-cache");
115a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre>
116a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * If it is only necessary to force a cached response to be validated by the
117a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * server, use the more efficient {@code max-age=0} instead: <pre>   {@code
118a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         connection.addRequestProperty("Cache-Control", "max-age=0");
119a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre>
120a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *
121a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Force a Cache Response</h3>
122a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Sometimes you'll want to show resources if they are available immediately,
123a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * but not otherwise. This can be used so your application can show
124a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <i>something</i> while waiting for the latest data to be downloaded. To
125a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * restrict a request to locally-cached resources, add the {@code
126a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * only-if-cached} directive: <pre>   {@code
127a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *     try {
128a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         connection.addRequestProperty("Cache-Control", "only-if-cached");
129a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         InputStream cached = connection.getInputStream();
130a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         // the resource was cached! show it
131a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *     } catch (FileNotFoundException e) {
132a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         // the resource was not cached
133a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *     }
134a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre>
135a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * This technique works even better in situations where a stale response is
136a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * better than no response. To permit stale cached responses, use the {@code
137a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * max-stale} directive with the maximum staleness in seconds: <pre>   {@code
138a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
139a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom *         connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
140a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre>
1418543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *
1428543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * <h3>Working With Earlier Releases</h3>
1438543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * This class was added in Android 4.0 (Ice Cream Sandwich). Use reflection to
1448543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * enable the response cache without impacting earlier releases: <pre>   {@code
1458543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *       try {
1468543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *           File httpCacheDir = new File(context.getCacheDir(), "http");
1478543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *           long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
1488543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *           Class.forName("android.net.http.HttpResponseCache")
1498543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *                   .getMethod("install", File.class, long.class)
1508543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *                   .invoke(null, httpCacheDir, httpCacheSize);
1518543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *       } catch (Exception httpResponseCacheNotAvailable) {
1528543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson *       }}</pre>
153a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */
15418c227ba72406c0b69ce9925a80113060d870256Jesse Wilsonpublic final class HttpResponseCache extends ResponseCache
15518c227ba72406c0b69ce9925a80113060d870256Jesse Wilson        implements Closeable, ExtendedResponseCache {
156a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
157a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    private final libcore.net.http.HttpResponseCache delegate;
158a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
159a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    private HttpResponseCache(File directory, long maxSize) throws IOException {
160a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        this.delegate = new libcore.net.http.HttpResponseCache(directory, maxSize);
161a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
162a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
163a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
164a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Returns the currently-installed {@code HttpResponseCache}, or null if
165a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * there is no cache installed or it is not a {@code HttpResponseCache}.
166a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
167a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public static HttpResponseCache getInstalled() {
168a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        ResponseCache installed = ResponseCache.getDefault();
169a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return installed instanceof HttpResponseCache ? (HttpResponseCache) installed : null;
170a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
171a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
172a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
173a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Creates a new HTTP response cache and {@link ResponseCache#setDefault
174a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * sets it} as the system default cache.
175a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     *
176a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * @param directory the directory to hold cache data.
177a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * @param maxSize the maximum size of the cache in bytes.
178a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * @return the newly-installed cache
179a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * @throws IOException if {@code directory} cannot be used for this cache.
180a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     *     Most applications should respond to this exception by logging a
181a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     *     warning.
182a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
183a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public static HttpResponseCache install(File directory, long maxSize) throws IOException {
184a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        HttpResponseCache installed = getInstalled();
185a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        if (installed != null) {
186a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            // don't close and reopen if an equivalent cache is already installed
187a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            DiskLruCache installedCache = installed.delegate.getCache();
188a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            if (installedCache.getDirectory().equals(directory)
189a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom                    && installedCache.maxSize() == maxSize
190a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom                    && !installedCache.isClosed()) {
191a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom                return installed;
192a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            } else {
193a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom                IoUtils.closeQuietly(installed);
194a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            }
195a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        }
196a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
197a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        HttpResponseCache result = new HttpResponseCache(directory, maxSize);
198a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        ResponseCache.setDefault(result);
199a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return result;
200a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
201a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
202a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    @Override public CacheResponse get(URI uri, String requestMethod,
203a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            Map<String, List<String>> requestHeaders) throws IOException {
204a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.get(uri, requestMethod, requestHeaders);
205a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
206a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
207a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException {
208a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.put(uri, urlConnection);
209a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
210a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
211a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
212a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Returns the number of bytes currently being used to store the values in
213a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * this cache. This may be greater than the {@link #maxSize} if a background
214a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * deletion is pending.
215a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
216a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public long size() {
217a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.getCache().size();
218a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
219a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
220a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
221a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Returns the maximum number of bytes that this cache should use to store
222a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * its data.
223a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
224a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public long maxSize() {
225a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.getCache().maxSize();
226a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
227a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
228a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
229a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Force buffered operations to the filesystem. This ensures that responses
230a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * written to the cache will be available the next time the cache is opened,
231a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * even if this process is killed.
232a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
233a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public void flush() {
234a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        try {
23598e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson            delegate.getCache().flush();
236a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        } catch (IOException ignored) {
237a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        }
238a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
239a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
240a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
241a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Returns the number of HTTP requests that required the network to either
242a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * supply a response or validate a locally cached response.
243a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
244a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public int getNetworkCount() {
245a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.getNetworkCount();
246a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
247a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
248a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
249a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Returns the number of HTTP requests whose response was provided by the
250a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * cache. This may include conditional {@code GET} requests that were
251a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * validated over the network.
252a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
253a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public int getHitCount() {
254a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.getHitCount();
255a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
256a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
257a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
258a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Returns the total number of HTTP requests that were made. This includes
259a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * both client requests and requests that were made on the client's behalf
260a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * to handle a redirects and retries.
261a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
262a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public int getRequestCount() {
263a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        return delegate.getRequestCount();
264a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
265a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
26618c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    /** @hide */
26718c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    @Override public void trackResponse(ResponseSource source) {
26818c227ba72406c0b69ce9925a80113060d870256Jesse Wilson        delegate.trackResponse(source);
26918c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    }
27018c227ba72406c0b69ce9925a80113060d870256Jesse Wilson
27118c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    /** @hide */
27218c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    @Override public void trackConditionalCacheHit() {
27318c227ba72406c0b69ce9925a80113060d870256Jesse Wilson        delegate.trackConditionalCacheHit();
27418c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    }
27518c227ba72406c0b69ce9925a80113060d870256Jesse Wilson
27618c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    /** @hide */
27718c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    @Override public void update(CacheResponse conditionalCacheHit, HttpURLConnection connection) {
27818c227ba72406c0b69ce9925a80113060d870256Jesse Wilson        delegate.update(conditionalCacheHit, connection);
27918c227ba72406c0b69ce9925a80113060d870256Jesse Wilson    }
28018c227ba72406c0b69ce9925a80113060d870256Jesse Wilson
281a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
282a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Uninstalls the cache and releases any active resources. Stored contents
283a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * will remain on the filesystem.
284a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
285a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    @Override public void close() throws IOException {
286a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        if (ResponseCache.getDefault() == this) {
287a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            ResponseCache.setDefault(null);
288a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        }
289a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        delegate.getCache().close();
290a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
291a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom
292a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    /**
293a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     * Uninstalls the cache and deletes all of its stored contents.
294a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom     */
295a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    public void delete() throws IOException {
296a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        if (ResponseCache.getDefault() == this) {
297a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom            ResponseCache.setDefault(null);
298a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        }
299a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        delegate.getCache().delete();
300a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom    }
301a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom}
302