CacheManager.java revision 0acb1c32fa002a648c8090f622b0094f406d5411
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.webkit;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
207cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilsonimport android.net.http.AndroidHttpClient;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.http.Headers;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.FileUtils;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream;
282036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Klobaimport java.io.FilenameFilter;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream;
322036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Klobaimport java.util.List;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3545a9a14006214e6478311ffcb980e766702d5a76Doug Zongker
364140faeebbfa23d56068c1862b2913fb62145f4fBrian Carlstromimport com.android.org.bouncycastle.crypto.Digest;
374140faeebbfa23d56068c1862b2913fb62145f4fBrian Carlstromimport com.android.org.bouncycastle.crypto.digests.SHA1Digest;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
40303bc083c5a158ff240be658ac30d201cad56a18Steve Block * Manages the HTTP cache used by an application's {@link WebView} instances.
41c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick * @deprecated Access to the HTTP cache will be removed in a future release.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
43303bc083c5a158ff240be658ac30d201cad56a18Steve Block// The class CacheManager provides the persistent cache of content that is
44303bc083c5a158ff240be658ac30d201cad56a18Steve Block// received over the network. The component handles parsing of HTTP headers and
45303bc083c5a158ff240be658ac30d201cad56a18Steve Block// utilizes the relevant cache headers to determine if the content should be
46303bc083c5a158ff240be658ac30d201cad56a18Steve Block// stored and if so, how long it is valid for. Network requests are provided to
47303bc083c5a158ff240be658ac30d201cad56a18Steve Block// this component and if they can not be resolved by the cache, the HTTP headers
48303bc083c5a158ff240be658ac30d201cad56a18Steve Block// are attached, as appropriate, to the request for revalidation of content. The
49303bc083c5a158ff240be658ac30d201cad56a18Steve Block// class also manages the cache size.
50303bc083c5a158ff240be658ac30d201cad56a18Steve Block//
51303bc083c5a158ff240be658ac30d201cad56a18Steve Block// CacheManager may only be used if your activity contains a WebView.
52c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick@Deprecated
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class CacheManager {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String LOGTAG = "cache";
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String HEADER_KEY_IFMODIFIEDSINCE = "if-modified-since";
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String HEADER_KEY_IFNONEMATCH = "if-none-match";
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static File mBaseDir;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
62f0c443deca49d597c8268ef3b0f7198976073241Ben Murdoch    /**
63303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Represents a resource stored in the HTTP cache. Instances of this class
64303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * can be obtained by calling
65303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>))}.
66c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick     * @deprecated Access to the HTTP cache will be removed in a future release.
67f0c443deca49d597c8268ef3b0f7198976073241Ben Murdoch     */
68c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick    @Deprecated
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class CacheResult {
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // these fields are saved to the database
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int httpStatusCode;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long contentLength;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long expires;
74e64c5567de20d06ac7ed1f5a01f018991cd40a52Grace Kloba        String expiresString;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String localPath;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String lastModified;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String etag;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String mimeType;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String location;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String encoding;
810b956e1353a691674cb22c899c5a444b92532b60Grace Kloba        String contentdisposition;
8260708a75120c4469dc2683485301ff9ee3b022e0Leon Clarke        String crossDomain;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // these fields are NOT saved to the database
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputStream inStream;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        OutputStream outStream;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        File outFile;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
89303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
90303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the status code of this cache entry.
91303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The status code of this cache entry
92303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getHttpStatusCode() {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return httpStatusCode;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
97303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
98303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the content length of this cache entry.
99303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The content length of this cache entry
100303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public long getContentLength() {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return contentLength;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
105303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
106303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the path of the file used to store the content of this cache
107303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * entry, relative to the base directory of the cache. See
108303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * {@link CacheManager#getCacheFileBaseDir CacheManager.getCacheFileBaseDir()}.
109303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The path of the file used to store this cache entry
110303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getLocalPath() {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return localPath;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
115303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
116303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the expiry date of this cache entry, expressed in milliseconds
117303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * since midnight, January 1, 1970 UTC.
118303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The expiry date of this cache entry
119303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public long getExpires() {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return expires;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
124303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
125303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the expiry date of this cache entry, expressed as a string.
126303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The expiry date of this cache entry
127303bc083c5a158ff240be658ac30d201cad56a18Steve Block         *
128303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
129e64c5567de20d06ac7ed1f5a01f018991cd40a52Grace Kloba        public String getExpiresString() {
130e64c5567de20d06ac7ed1f5a01f018991cd40a52Grace Kloba            return expiresString;
131e64c5567de20d06ac7ed1f5a01f018991cd40a52Grace Kloba        }
132e64c5567de20d06ac7ed1f5a01f018991cd40a52Grace Kloba
133303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
134303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the date at which this cache entry was last modified, expressed
135303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * as a string.
136303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The date at which this cache entry was last modified
137303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getLastModified() {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return lastModified;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
142303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
143303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the entity tag of this cache entry.
144303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The entity tag of this cache entry
145303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getETag() {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return etag;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
150303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
151303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the MIME type of this cache entry.
152303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The MIME type of this cache entry
153303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getMimeType() {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mimeType;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
158303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
159303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the value of the HTTP 'Location' header with which this cache
160303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * entry was received.
161303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The HTTP 'Location' header for this cache entry
162303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getLocation() {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return location;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
167303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
168303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the encoding of this cache entry.
169303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The encoding of this cache entry
170303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getEncoding() {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return encoding;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
175303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
176303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the value of the HTTP 'Content-Disposition' header with which
177303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * this cache entry was received.
178303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return The HTTP 'Content-Disposition' header for this cache entry
179303bc083c5a158ff240be658ac30d201cad56a18Steve Block         *
180303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1810b956e1353a691674cb22c899c5a444b92532b60Grace Kloba        public String getContentDisposition() {
1820b956e1353a691674cb22c899c5a444b92532b60Grace Kloba            return contentdisposition;
1830b956e1353a691674cb22c899c5a444b92532b60Grace Kloba        }
1840b956e1353a691674cb22c899c5a444b92532b60Grace Kloba
185303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
186303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets the input stream to the content of this cache entry, to allow
187303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * content to be read. See
188303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>)}.
189303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return An input stream to the content of this cache entry
190303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public InputStream getInputStream() {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return inStream;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
195303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
196303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Gets an output stream to the content of this cache entry, to allow
197303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * content to be written. See
198303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * {@link CacheManager#saveCacheFile CacheManager.saveCacheFile(String, CacheResult)}.
199303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @return An output stream to the content of this cache entry
200303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
201303bc083c5a158ff240be658ac30d201cad56a18Steve Block        // Note that this is always null for objects returned by getCacheFile()!
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public OutputStream getOutputStream() {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return outStream;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
206303bc083c5a158ff240be658ac30d201cad56a18Steve Block
207303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
208303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Sets an input stream to the content of this cache entry.
209303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @param stream An input stream to the content of this cache entry
210303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setInputStream(InputStream stream) {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.inStream = stream;
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
215303bc083c5a158ff240be658ac30d201cad56a18Steve Block        /**
216303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * Sets the encoding of this cache entry.
217303bc083c5a158ff240be658ac30d201cad56a18Steve Block         * @param encoding The encoding of this cache entry
218303bc083c5a158ff240be658ac30d201cad56a18Steve Block         */
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setEncoding(String encoding) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.encoding = encoding;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
222b67529b905440e2ba550742773b927abad882c19Iain Merrick
223b67529b905440e2ba550742773b927abad882c19Iain Merrick        /**
224b67529b905440e2ba550742773b927abad882c19Iain Merrick         * @hide
225b67529b905440e2ba550742773b927abad882c19Iain Merrick         */
226b67529b905440e2ba550742773b927abad882c19Iain Merrick        public void setContentLength(long contentLength) {
227b67529b905440e2ba550742773b927abad882c19Iain Merrick            this.contentLength = contentLength;
228b67529b905440e2ba550742773b927abad882c19Iain Merrick        }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
232303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Initializes the HTTP cache. This method must be called before any
233303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * CacheManager methods are used. Note that this is called automatically
234303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * when a {@link WebView} is created.
235303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @param context The application context
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static void init(Context context) {
2380acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // This isn't actually where the real cache lives, but where we put files for the
2390acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // purpose of getCacheFile().
2400acb1c32fa002a648c8090f622b0094f406d5411Steve Block        mBaseDir = new File(context.getCacheDir(), "webviewCacheChromiumStaging");
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mBaseDir.exists()) {
2420acb1c32fa002a648c8090f622b0094f406d5411Steve Block            mBaseDir.mkdirs();
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
247303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Gets the base directory in which the files used to store the contents of
248303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * cache entries are placed. See
249303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * {@link CacheManager.CacheResult#getLocalPath CacheManager.CacheResult.getLocalPath()}.
250303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @return The base directory of the cache
251c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick     * @deprecated Access to the HTTP cache will be removed in a future release.
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
253c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick    @Deprecated
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static File getCacheFileBaseDir() {
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBaseDir;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
259303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Gets whether the HTTP cache is disabled.
260303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @return True if the HTTP cache is disabled
261c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick     * @deprecated Access to the HTTP cache will be removed in a future release.
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
263c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick    @Deprecated
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static boolean cacheDisabled() {
2651e17ecae25c8b56db6d168851b858aa3ef9a3b6aSteve Block        return false;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2682036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    /**
269303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Starts a cache transaction. Returns true if this is the only running
270303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * transaction. Otherwise, this transaction is nested inside currently
271303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * running transactions and false is returned.
272303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @return True if this is the only running transaction
273303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @deprecated This method no longer has any effect and always returns false
2742036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba     */
2752036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    @Deprecated
2762036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    public static boolean startCacheTransaction() {
2772036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba        return false;
2782036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    }
2792036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba
2802036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    /**
281303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Ends the innermost cache transaction and returns whether this was the
282303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * only running transaction.
283303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @return True if this was the only running transaction
284303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @deprecated This method no longer has any effect and always returns false
2852036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba     */
2862036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    @Deprecated
2872036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    public static boolean endCacheTransaction() {
2882036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba        return false;
2892036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba    }
2902036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
292ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * Gets the cache entry for the specified URL, or null if none is found.
293ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * If a non-null value is provided for the HTTP headers map, and the cache
294ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * entry needs validation, appropriate headers will be added to the map.
295ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * The input stream of the CacheEntry object should be closed by the caller
296ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * when access to the underlying file is no longer required.
297ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * @param url The URL for which a cache entry is requested
298ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * @param headers A map from HTTP header name to value, to be populated
299ffefba15e3a011836f037c185d4909a59995ff32Steve Block     *                for the returned cache entry
300ffefba15e3a011836f037c185d4909a59995ff32Steve Block     * @return The cache entry for the specified URL
301c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick     * @deprecated Access to the HTTP cache will be removed in a future release.
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
303c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick    @Deprecated
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static CacheResult getCacheFile(String url,
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Map<String, String> headers) {
3068c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba        return getCacheFile(url, 0, headers);
3078c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba    }
3088c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba
3090acb1c32fa002a648c8090f622b0094f406d5411Steve Block    static CacheResult getCacheFile(String url, long postIdentifier,
3100acb1c32fa002a648c8090f622b0094f406d5411Steve Block            Map<String, String> headers) {
311ffefba15e3a011836f037c185d4909a59995ff32Steve Block        CacheResult result = nativeGetCacheResult(url);
312ffefba15e3a011836f037c185d4909a59995ff32Steve Block        if (result == null) {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
315ffefba15e3a011836f037c185d4909a59995ff32Steve Block        // A temporary local file will have been created native side and localPath set
316ffefba15e3a011836f037c185d4909a59995ff32Steve Block        // appropriately.
317ffefba15e3a011836f037c185d4909a59995ff32Steve Block        File src = new File(mBaseDir, result.localPath);
318ffefba15e3a011836f037c185d4909a59995ff32Steve Block        try {
319ffefba15e3a011836f037c185d4909a59995ff32Steve Block            // Open the file here so that even if it is deleted, the content
320ffefba15e3a011836f037c185d4909a59995ff32Steve Block            // is still readable by the caller until close() is called.
321ffefba15e3a011836f037c185d4909a59995ff32Steve Block            result.inStream = new FileInputStream(src);
322ffefba15e3a011836f037c185d4909a59995ff32Steve Block        } catch (FileNotFoundException e) {
323ffefba15e3a011836f037c185d4909a59995ff32Steve Block            Log.v(LOGTAG, "getCacheFile(): Failed to open file: " + e);
324ffefba15e3a011836f037c185d4909a59995ff32Steve Block            // TODO: The files in the cache directory can be removed by the
325ffefba15e3a011836f037c185d4909a59995ff32Steve Block            // system. If it is gone, what should we do?
326ffefba15e3a011836f037c185d4909a59995ff32Steve Block            return null;
327808751fe7ac16bf7224cba284a318695d8093355Steve Block        }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32967ba204aa23e7d5a96ad241a1623e44976b51741Steve Block        // A null value for headers is used by CACHE_MODE_CACHE_ONLY to imply
33067ba204aa23e7d5a96ad241a1623e44976b51741Steve Block        // that we should provide the cache result even if it is expired.
33167ba204aa23e7d5a96ad241a1623e44976b51741Steve Block        // Note that a negative expires value means a time in the far future.
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (headers != null && result.expires >= 0
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && result.expires <= System.currentTimeMillis()) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (result.lastModified == null && result.etag == null) {
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
33767ba204aa23e7d5a96ad241a1623e44976b51741Steve Block            // Return HEADER_KEY_IFNONEMATCH or HEADER_KEY_IFMODIFIEDSINCE
33867ba204aa23e7d5a96ad241a1623e44976b51741Steve Block            // for requesting validation.
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (result.etag != null) {
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                headers.put(HEADER_KEY_IFNONEMATCH, result.etag);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (result.lastModified != null) {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                headers.put(HEADER_KEY_IFMODIFIEDSINCE, result.lastModified);
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3472e5c150e746647a1ce5c10e1708debbf06c45ea7Derek Sollenberger        if (DebugFlags.CACHE_MANAGER) {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.v(LOGTAG, "getCacheFile for url " + url);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Given a url and its full headers, returns CacheResult if a local cache
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can be stored. Otherwise returns null. The mimetype is passed in so that
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the function can use the mimetype that will be passed to WebCore which
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * could be different from the mimetype defined in the headers.
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * forceCache is for out-of-package callers to force creation of a
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CacheResult, and is used to supply surrogate responses for URL
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interception.
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return CacheResult for a given url
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
364303bc083c5a158ff240be658ac30d201cad56a18Steve Block    static CacheResult createCacheFile(String url, int statusCode,
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Headers headers, String mimeType, boolean forceCache) {
3660acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // This method is public but hidden. We break functionality.
3670acb1c32fa002a648c8090f622b0094f406d5411Steve Block        return null;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
371303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * Adds a cache entry to the HTTP cache for the specicifed URL. Also closes
372303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * the cache entry's output stream.
373303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @param url The URL for which the cache entry should be added
374303bc083c5a158ff240be658ac30d201cad56a18Steve Block     * @param cacheResult The cache entry to add
375c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick     * @deprecated Access to the HTTP cache will be removed in a future release.
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
377c96235deb9f4d08285f3b1a2c28ea9f771b40f47Iain Merrick    @Deprecated
378303bc083c5a158ff240be658ac30d201cad56a18Steve Block    public static void saveCacheFile(String url, CacheResult cacheResult) {
379303bc083c5a158ff240be658ac30d201cad56a18Steve Block        saveCacheFile(url, 0, cacheResult);
3808c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba    }
3818c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba
3828c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba    static void saveCacheFile(String url, long postIdentifier,
3838c92c39b858ae73a1b08ed698887efa98ced987cGrace Kloba            CacheResult cacheRet) {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cacheRet.outStream.close();
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (IOException e) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3900acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // This method is exposed in the public API but the API provides no
3910acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // way to obtain a new CacheResult object with a non-null output
3920acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // stream ...
3930acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // - CacheResult objects returned by getCacheFile() have a null
3940acb1c32fa002a648c8090f622b0094f406d5411Steve Block        //   output stream.
3950acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // - new CacheResult objects have a null output stream and no
3960acb1c32fa002a648c8090f622b0094f406d5411Steve Block        //   setter is provided.
3970acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // Since this method throws a null pointer exception in this case,
3980acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // it is effectively useless from the point of view of the public
3990acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // API.
4000acb1c32fa002a648c8090f622b0094f406d5411Steve Block        //
4010acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // With the Chromium HTTP stack we continue to throw the same
4020acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // exception for 'backwards compatibility' with the Android HTTP
4030acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // stack.
4040acb1c32fa002a648c8090f622b0094f406d5411Steve Block        //
4050acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // This method is not used from within this package, and for public API
4060acb1c32fa002a648c8090f622b0094f406d5411Steve Block        // use, we should already have thrown an exception above.
4070acb1c32fa002a648c8090f622b0094f406d5411Steve Block        assert false;
408998c05b3b5db124a31da1ac38af0e97bca114122Grace Kloba    }
409998c05b3b5db124a31da1ac38af0e97bca114122Grace Kloba
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
41167ba204aa23e7d5a96ad241a1623e44976b51741Steve Block     * Remove all cache files.
41267ba204aa23e7d5a96ad241a1623e44976b51741Steve Block     *
41367ba204aa23e7d5a96ad241a1623e44976b51741Steve Block     * @return Whether the removal succeeded.
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static boolean removeAllCacheFiles() {
4162036dbab1726c34953360a7a56d6b9ef1f2aa7ddGrace Kloba        // delete cache files in a separate thread to not block UI.
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Runnable clearCache = new Runnable() {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void run() {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // delete all cache files
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String[] files = mBaseDir.list();
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // if mBaseDir doesn't exist, files can be null.
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (files != null) {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        for (int i = 0; i < files.length; i++) {
425543221fc4b9dd16db2c687cd59f1eeea8d89c5a5Cary Clark                            File f = new File(mBaseDir, files[i]);
426543221fc4b9dd16db2c687cd59f1eeea8d89c5a5Cary Clark                            if (!f.delete()) {
427543221fc4b9dd16db2c687cd59f1eeea8d89c5a5Cary Clark                                Log.e(LOGTAG, f.getPath() + " delete failed.");
428543221fc4b9dd16db2c687cd59f1eeea8d89c5a5Cary Clark                            }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (SecurityException e) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Ignore SecurityExceptions.
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new Thread(clearCache).start();
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
440e8492473a94e827b9a73f1fa4f5741e85c0e832cSteve Block    private static native CacheResult nativeGetCacheResult(String url);
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
442