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 1950a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fullerimport com.android.okhttp.Cache; 2050a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fullerimport com.android.okhttp.AndroidShimResponseCache; 2150a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fullerimport com.android.okhttp.OkCacheContainer; 2250a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller 23a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.io.Closeable; 24a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.io.File; 25a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.io.IOException; 26a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.CacheRequest; 27a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.CacheResponse; 28a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.ResponseCache; 29a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.URI; 30a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.net.URLConnection; 31a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.util.List; 32a7284f0e72745d66155e1e282fc07113332790faBrian Carlstromimport java.util.Map; 33a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 34a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom/** 35a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Caches HTTP and HTTPS responses to the filesystem so they may be reused, 36ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * saving time and bandwidth. This class supports {@link 37ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * java.net.HttpURLConnection} and {@link javax.net.ssl.HttpsURLConnection}; 383bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * there is no platform-provided cache for {@code DefaultHttpClient} or 393bdd327f8532a79b83f575cc62e8eb09a1f93f3dNarayan Kamath * {@code AndroidHttpClient}. 40a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 41a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Installing an HTTP response cache</h3> 42a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Enable caching of all of your application's HTTP requests by installing the 43a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * cache at application startup. For example, this code installs a 10 MiB cache 44ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * in the {@link android.content.Context#getCacheDir() application-specific 45ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * cache directory} of the filesystem}: <pre> {@code 46a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * protected void onCreate(Bundle savedInstanceState) { 47a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * ... 48a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 49a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * try { 50a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * File httpCacheDir = new File(context.getCacheDir(), "http"); 51a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * long httpCacheSize = 10 * 1024 * 1024; // 10 MiB 52a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * HttpResponseCache.install(httpCacheDir, httpCacheSize); 53a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * } catch (IOException e) { 54a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Log.i(TAG, "HTTP response cache installation failed:" + e); 55a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * } 56a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * } 57a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 58a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * protected void onStop() { 59a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * ... 60a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 61a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * HttpResponseCache cache = HttpResponseCache.getInstalled(); 62a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * if (cache != null) { 63a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * cache.flush(); 64a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * } 65a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }}</pre> 66a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * This cache will evict entries as necessary to keep its size from exceeding 67a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 10 MiB. The best cache size is application specific and depends on the size 68a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * and frequency of the files being downloaded. Increasing the limit may improve 69a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * the hit rate, but it may also just waste filesystem space! 70a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 71a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <p>For some applications it may be preferable to create the cache in the 7298e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * external storage directory. <strong>There are no access controls on the 7398e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * external storage directory so it should not be used for caches that could 7498e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * contain private data.</strong> Although it often has more free space, 7598e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * external storage is optional and—even if available—can disappear 7698e8b19c7bc422600a7a27819311d0059b5af2daJesse Wilson * during use. Retrieve the external cache directory using {@link 77ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * android.content.Context#getExternalCacheDir()}. If this method returns null, 78ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * your application should fall back to either not caching or caching on 79ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * non-external storage. If the external storage is removed during use, the 80ae69120b0f56da6d2c3f6661be0885b7b9283c12Neil Fuller * cache hit rate will drop to zero and ongoing cache reads will fail. 81a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 82a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <p>Flushing the cache forces its data to the filesystem. This ensures that 83a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * all responses written to the cache will be readable the next time the 84a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * activity starts. 85a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 86a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Cache Optimization</h3> 87a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * To measure cache effectiveness, this class tracks three statistics: 88a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <ul> 89a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <li><strong>{@link #getRequestCount() Request Count:}</strong> the number 90a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * of HTTP requests issued since this cache was created. 91a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <li><strong>{@link #getNetworkCount() Network Count:}</strong> the 92a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * number of those requests that required network use. 93a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <li><strong>{@link #getHitCount() Hit Count:}</strong> the number of 94a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * those requests whose responses were served by the cache. 95a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * </ul> 96a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Sometimes a request will result in a conditional cache hit. If the cache 97a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * contains a stale copy of the response, the client will issue a conditional 98a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * {@code GET}. The server will then send either the updated response if it has 99a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * changed, or a short 'not modified' response if the client's copy is still 100a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * valid. Such responses increment both the network count and hit count. 101a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 102a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <p>The best way to improve the cache hit rate is by configuring the web 103a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * server to return cacheable responses. Although this client honors all <a 104a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * href="http://www.ietf.org/rfc/rfc2616.txt">HTTP/1.1 (RFC 2068)</a> cache 105a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * headers, it doesn't cache partial responses. 106a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 107a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Force a Network Response</h3> 108a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * In some situations, such as after a user clicks a 'refresh' button, it may be 109a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * necessary to skip the cache, and fetch data directly from the server. To force 110a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * a full refresh, add the {@code no-cache} directive: <pre> {@code 111a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * connection.addRequestProperty("Cache-Control", "no-cache"); 112a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre> 113a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * If it is only necessary to force a cached response to be validated by the 114a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * server, use the more efficient {@code max-age=0} instead: <pre> {@code 115a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * connection.addRequestProperty("Cache-Control", "max-age=0"); 116a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre> 117a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 118a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <h3>Force a Cache Response</h3> 119a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Sometimes you'll want to show resources if they are available immediately, 120a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * but not otherwise. This can be used so your application can show 121a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * <i>something</i> while waiting for the latest data to be downloaded. To 122a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * restrict a request to locally-cached resources, add the {@code 123a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * only-if-cached} directive: <pre> {@code 124a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * try { 125a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * connection.addRequestProperty("Cache-Control", "only-if-cached"); 126a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * InputStream cached = connection.getInputStream(); 127a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * // the resource was cached! show it 128a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * } catch (FileNotFoundException e) { 129a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * // the resource was not cached 130a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * } 131a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre> 132a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * This technique works even better in situations where a stale response is 133a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * better than no response. To permit stale cached responses, use the {@code 134a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * max-stale} directive with the maximum staleness in seconds: <pre> {@code 135a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale 136a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale); 137a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * }</pre> 1388543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * 1398543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * <h3>Working With Earlier Releases</h3> 1408543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * This class was added in Android 4.0 (Ice Cream Sandwich). Use reflection to 1418543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * enable the response cache without impacting earlier releases: <pre> {@code 1428543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * try { 1438543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * File httpCacheDir = new File(context.getCacheDir(), "http"); 1448543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * long httpCacheSize = 10 * 1024 * 1024; // 10 MiB 1458543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * Class.forName("android.net.http.HttpResponseCache") 1468543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * .getMethod("install", File.class, long.class) 1478543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * .invoke(null, httpCacheDir, httpCacheSize); 1488543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * } catch (Exception httpResponseCacheNotAvailable) { 1498543b5480d9c261e72965f64a7bc918eb183ea25Jesse Wilson * }}</pre> 150a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 15150a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fullerpublic final class HttpResponseCache extends ResponseCache implements Closeable, OkCacheContainer { 152a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 15350a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller private final AndroidShimResponseCache delegate; 154a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 15550a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller private HttpResponseCache(AndroidShimResponseCache delegate) { 15668a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath this.delegate = delegate; 157a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 158a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 159a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 160a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Returns the currently-installed {@code HttpResponseCache}, or null if 161a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * there is no cache installed or it is not a {@code HttpResponseCache}. 162a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 163a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public static HttpResponseCache getInstalled() { 164a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom ResponseCache installed = ResponseCache.getDefault(); 16550a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller if (installed instanceof HttpResponseCache) { 16650a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return (HttpResponseCache) installed; 16768a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath } 16868a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath return null; 169a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 170a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 171a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 17250a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller * Creates a new HTTP response cache and sets it as the system default cache. 173a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * 174a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * @param directory the directory to hold cache data. 175a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * @param maxSize the maximum size of the cache in bytes. 176a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * @return the newly-installed cache 177a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * @throws IOException if {@code directory} cannot be used for this cache. 178a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Most applications should respond to this exception by logging a 179a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * warning. 180a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 18150a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller public static synchronized HttpResponseCache install(File directory, long maxSize) 18250a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller throws IOException { 18368a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath ResponseCache installed = ResponseCache.getDefault(); 18450a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller if (installed instanceof HttpResponseCache) { 18550a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller HttpResponseCache installedResponseCache = (HttpResponseCache) installed; 186a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom // don't close and reopen if an equivalent cache is already installed 18750a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller AndroidShimResponseCache trueResponseCache = installedResponseCache.delegate; 18850a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller if (trueResponseCache.isEquivalent(directory, maxSize)) { 18950a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return installedResponseCache; 190a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } else { 19168a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath // The HttpResponseCache that owns this object is about to be replaced. 19250a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller trueResponseCache.close(); 193a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 194a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 195a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 19650a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller AndroidShimResponseCache trueResponseCache = 19750a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller AndroidShimResponseCache.create(directory, maxSize); 19850a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller HttpResponseCache newResponseCache = new HttpResponseCache(trueResponseCache); 19950a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller ResponseCache.setDefault(newResponseCache); 20050a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return newResponseCache; 201a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 202a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 203a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom @Override public CacheResponse get(URI uri, String requestMethod, 204a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom Map<String, List<String>> requestHeaders) throws IOException { 205a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom return delegate.get(uri, requestMethod, requestHeaders); 206a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 207a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 208a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException { 209a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom return delegate.put(uri, urlConnection); 210a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 211a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 212a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 213a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Returns the number of bytes currently being used to store the values in 214a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * this cache. This may be greater than the {@link #maxSize} if a background 21550a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller * deletion is pending. {@code -1} is returned if the size cannot be determined. 216a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 217a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public long size() { 21850a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller try { 21950a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return delegate.size(); 22050a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller } catch (IOException e) { 22150a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller // This can occur if the cache failed to lazily initialize. 22250a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return -1; 22350a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller } 224a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 225a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 226a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 227a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Returns the maximum number of bytes that this cache should use to store 228a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * its data. 229a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 230a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public long maxSize() { 23150a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return delegate.maxSize(); 232a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 233a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 234a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 235a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Force buffered operations to the filesystem. This ensures that responses 236a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * written to the cache will be available the next time the cache is opened, 237a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * even if this process is killed. 238a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 239a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public void flush() { 240a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom try { 24168a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath delegate.flush(); 242a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } catch (IOException ignored) { 243a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 244a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 245a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 246a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 247a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Returns the number of HTTP requests that required the network to either 248a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * supply a response or validate a locally cached response. 249a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 250a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public int getNetworkCount() { 251a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom return delegate.getNetworkCount(); 252a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 253a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 254a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 255a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Returns the number of HTTP requests whose response was provided by the 256a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * cache. This may include conditional {@code GET} requests that were 257a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * validated over the network. 258a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 259a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public int getHitCount() { 260a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom return delegate.getHitCount(); 261a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 262a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 263a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 264a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Returns the total number of HTTP requests that were made. This includes 265a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * both client requests and requests that were made on the client's behalf 266a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * to handle a redirects and retries. 267a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 268a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public int getRequestCount() { 269a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom return delegate.getRequestCount(); 270a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 271a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 272a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 273a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Uninstalls the cache and releases any active resources. Stored contents 274a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * will remain on the filesystem. 275a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 276a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom @Override public void close() throws IOException { 27750a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller if (ResponseCache.getDefault() == this) { 278a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom ResponseCache.setDefault(null); 279a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 28068a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath delegate.close(); 281a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 282a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom 283a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom /** 284a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom * Uninstalls the cache and deletes all of its stored contents. 285a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom */ 286a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom public void delete() throws IOException { 28750a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller if (ResponseCache.getDefault() == this) { 288a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom ResponseCache.setDefault(null); 289a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 29068a3cd7955479d3f77fe3facd20c5ded7dafc68eNarayan Kamath delegate.delete(); 291a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom } 29250a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller 29350a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller /** @hide Needed for OkHttp integration. */ 29450a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller @Override 29550a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller public Cache getCache() { 29650a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller return delegate.getCache(); 29750a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller } 29850a01d89606b40dd151ad407d05c3b2867bbdbadNeil Fuller 299a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom} 300