Loading core/java/android/webkit/BrowserFrame.java +3 −2 Original line number Diff line number Diff line /* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2010, Code Aurora Forum. All rights reserved. * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -30,6 +30,7 @@ import android.net.WebAddress; import android.net.http.SslCertificate; import android.os.Handler; import android.os.Message; import android.os.SystemProperties; import android.provider.OpenableColumns; import android.util.Log; import android.util.TypedValue; Loading Loading @@ -195,7 +196,7 @@ class BrowserFrame extends Handler { ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); if (am.getMemoryClass() > 16) { sJavaBridge.setCacheSize(8 * 1024 * 1024); sJavaBridge.setCacheSize(SystemProperties.getInt("webkit.cache.size", 8 * 1024 * 1024)); } else { sJavaBridge.setCacheSize(4 * 1024 * 1024); } Loading core/java/android/webkit/CacheManager.java +14 −3 Original line number Diff line number Diff line /* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -20,6 +21,7 @@ import android.content.Context; import android.net.http.AndroidHttpClient; import android.net.http.Headers; import android.os.FileUtils; import android.os.SystemProperties; import android.util.Log; import java.io.File; import java.io.FileInputStream; Loading Loading @@ -57,11 +59,14 @@ public final class CacheManager { private static final String MAX_AGE = "max-age"; private static final String MANIFEST_MIME = "text/cache-manifest"; private static long CACHE_THRESHOLD = 6 * 1024 * 1024; private static long CACHE_TRIM_AMOUNT = 2 * 1024 * 1024; private static final long CACHE_THRESHOLD_DEF = 6 * 1024 * 1024; private static final long CACHE_TRIM_AMOUNT_DEF = 2 * 1024 * 1024; private static long CACHE_THRESHOLD = CACHE_THRESHOLD_DEF; private static long CACHE_TRIM_AMOUNT = CACHE_TRIM_AMOUNT_DEF; // Limit the maximum cache file size to half of the normal capacity static long CACHE_MAX_SIZE = (CACHE_THRESHOLD - CACHE_TRIM_AMOUNT) / 2; static long CACHE_MAX_SIZE = (CACHE_THRESHOLD_DEF - CACHE_TRIM_AMOUNT_DEF) / 2; private static boolean mDisabled; Loading Loading @@ -100,6 +105,7 @@ public final class CacheManager { String encoding; String contentdisposition; String crossDomain; int accessCounter; // these fields are NOT saved to the database InputStream inStream; Loading Loading @@ -181,6 +187,10 @@ public final class CacheManager { removeAllCacheFiles(); mClearCacheOnInit = false; } CACHE_THRESHOLD = SystemProperties.getLong("nw.cache.threshold", CACHE_THRESHOLD_DEF); CACHE_TRIM_AMOUNT = SystemProperties.getLong("nw.cache.trimamount", CACHE_TRIM_AMOUNT_DEF); CACHE_MAX_SIZE = (CACHE_THRESHOLD - CACHE_TRIM_AMOUNT) / 2; } /** Loading Loading @@ -545,6 +555,7 @@ public final class CacheManager { } static void trimCacheIfNeeded() { mDataBase.flushCacheStat(); if (mDataBase.getCacheTotalSize() > CACHE_THRESHOLD) { List<String> pathList = mDataBase.trimCache(CACHE_TRIM_AMOUNT); int size = pathList.size(); Loading core/java/android/webkit/WebViewDatabase.java +189 −4 Original line number Diff line number Diff line /* * Copyright (C) 2007 The Android Open Source Project * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -20,7 +21,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.HashMap; import java.util.Map.Entry; import android.content.ContentValues; Loading @@ -30,6 +33,7 @@ import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteStatement; import android.os.SystemProperties; import android.util.Log; import android.webkit.CookieManager.Cookie; import android.webkit.CacheManager.CacheResult; Loading @@ -51,10 +55,11 @@ public class WebViewDatabase { // 7 -> 8 Move cache to its own db // 8 -> 9 Store both scheme and host when storing passwords // 9 -> 10 Update httpauth table UNIQUE private static final int CACHE_DATABASE_VERSION = 4; private static final int CACHE_DATABASE_VERSION = 5; // 1 -> 2 Add expires String // 2 -> 3 Add content-disposition // 3 -> 4 Add crossdomain (For x-permitted-cross-domain-policies header) // 4 -> 5 Add last-acces-time, access-counter, weight private static WebViewDatabase mInstance = null; Loading Loading @@ -129,6 +134,12 @@ public class WebViewDatabase { private static final String CACHE_CROSSDOMAIN_COL = "crossdomain"; private static final String CACHE_LASTACCESSTIME_COL = "lastaccesstime"; private static final String CACHE_ACCESSCOUNTER_COL = "accesscounter"; private static final String CACHE_WEIGHT_COL = "weight"; // column id strings for "password" table private static final String PASSWORD_HOST_COL = "host"; Loading Loading @@ -170,9 +181,104 @@ public class WebViewDatabase { private static int mCacheContentLengthColIndex; private static int mCacheContentDispositionColIndex; private static int mCacheCrossDomainColIndex; private static int mCacheLastAccessTimeIndex; private static int mCacheAccessCounterIndex; private static int mCacheWeightIndex; private static int mCacheTransactionRefcount; private static final int CACHE_STAT_ID_OTHER = 0; private static final int CACHE_STAT_ID_HTML = 1; private static final int CACHE_STAT_ID_CSS = 2; private static final int CACHE_STAT_ID_JS = 3; private static final int CACHE_STAT_ID_IMAGE = 4; private static final String CACHE_ORDER_BY_DEF = CACHE_EXPIRES_COL; private static String CACHE_ORDER_BY = CACHE_ORDER_BY_DEF; private static final int CACHE_EVICT_EXPIRED_DEF = 0; private static final long CACHE_PRIO_ADVANCE_STEP_DEF = 0; private static final long CACHE_WEIGHT_ADVANCE_STEP_DEF = 0; private static int CACHE_EVICT_EXPIRED = CACHE_EVICT_EXPIRED_DEF; private static long CACHE_ADVANCE_STEP_PRIO = CACHE_PRIO_ADVANCE_STEP_DEF; private static long CACHE_ADVANCE_STEP_WEIGHT = CACHE_WEIGHT_ADVANCE_STEP_DEF; private static class CacheAccessStat { long mLastAccessTime = 0; int mCacheAccessCounter = 0; int mCacheItemPriority = 0; long mContentLength = 0; long mWeight = 0; public CacheAccessStat(CacheResult c) { mCacheAccessCounter = c.accessCounter; mCacheItemPriority = getCacheItemPriority(c.getMimeType()); mContentLength = c.getContentLength(); hit(); } public void hit() { mCacheAccessCounter++; mLastAccessTime = System.currentTimeMillis(); mWeight = mLastAccessTime + CACHE_ADVANCE_STEP_PRIO * mCacheItemPriority; mWeight += CACHE_ADVANCE_STEP_WEIGHT * normalize(mContentLength/mCacheAccessCounter); } int getCacheStatId(String mimeType) { if (mimeType.contains("image")) { return CACHE_STAT_ID_IMAGE; } if (mimeType.contains("javascript") || mimeType.contains("js")) { return CACHE_STAT_ID_JS; } if (mimeType.contains("css")) { return CACHE_STAT_ID_CSS; } if (mimeType.contains("html")) { return CACHE_STAT_ID_HTML; } return CACHE_STAT_ID_OTHER; } /** * Get resource priority */ int getCacheItemPriority(String mimeType) { int id = getCacheStatId(mimeType); switch (id) { case CACHE_STAT_ID_CSS: case CACHE_STAT_ID_HTML: return 2; case CACHE_STAT_ID_JS: return 1; case CACHE_STAT_ID_IMAGE: return 0; } return -1; } int normalize(long i) { int normalized = 0; if ((i & (i - 1)) != 0) { normalized += 1; } for (int index = 16; index >= 2; index = index/2 ) { if ((i >> index) != 0) { normalized += index; i >>= index; } } if ((i >> 1) != 0) { normalized += 1; } return (32 - normalized); } } private final Object mCacheStatLock = new Object(); private static HashMap<String, CacheAccessStat> mCacheStat = new HashMap<String, CacheAccessStat>(); private WebViewDatabase() { // Singleton only, use getInstance() } Loading @@ -180,6 +286,12 @@ public class WebViewDatabase { public static synchronized WebViewDatabase getInstance(Context context) { if (mInstance == null) { mInstance = new WebViewDatabase(); CACHE_EVICT_EXPIRED = SystemProperties.getInt("nw.cache.evictexpired", CACHE_EVICT_EXPIRED_DEF); CACHE_ADVANCE_STEP_PRIO = SystemProperties.getLong("nw.cache.prioadvstep", CACHE_PRIO_ADVANCE_STEP_DEF); CACHE_ADVANCE_STEP_WEIGHT = SystemProperties.getLong("nw.cache.weightadvstep", CACHE_WEIGHT_ADVANCE_STEP_DEF); CACHE_ORDER_BY = SystemProperties.get("nw.cache.orderby", CACHE_ORDER_BY_DEF); try { mDatabase = context .openOrCreateDatabase(DATABASE_FILE, 0, null); Loading Loading @@ -275,6 +387,12 @@ public class WebViewDatabase { .getColumnIndex(CACHE_CONTENTDISPOSITION_COL); mCacheCrossDomainColIndex = mCacheInserter .getColumnIndex(CACHE_CROSSDOMAIN_COL); mCacheLastAccessTimeIndex = mCacheInserter .getColumnIndex(CACHE_LASTACCESSTIME_COL); mCacheAccessCounterIndex = mCacheInserter .getColumnIndex(CACHE_ACCESSCOUNTER_COL); mCacheWeightIndex = mCacheInserter .getColumnIndex(CACHE_WEIGHT_COL); } } Loading Loading @@ -385,6 +503,9 @@ public class WebViewDatabase { + CACHE_LOCATION_COL + " TEXT, " + CACHE_CONTENTLENGTH_COL + " INTEGER, " + CACHE_CONTENTDISPOSITION_COL + " TEXT, " + CACHE_CROSSDOMAIN_COL + " TEXT," + CACHE_LASTACCESSTIME_COL + " INTEGER," + CACHE_ACCESSCOUNTER_COL + " INTEGER," + CACHE_WEIGHT_COL + " INTEGER," + " UNIQUE (" + CACHE_URL_COL + ") ON CONFLICT REPLACE);"); mCacheDatabase.execSQL("CREATE INDEX cacheUrlIndex ON cache (" + CACHE_URL_COL + ")"); Loading Loading @@ -617,6 +738,45 @@ public class WebViewDatabase { return false; } /** * Update cache statistics */ CacheAccessStat updateCacheStat(String url, CacheResult c) { if (c.expires != 0) { CacheAccessStat cacheStat; synchronized (mCacheStatLock) { cacheStat = mCacheStat.get(url); if (cacheStat == null) { cacheStat = new CacheAccessStat(c); mCacheStat.put( url , cacheStat); } else { cacheStat.hit(); } } return cacheStat; } return null; } /** * Flush cache statistics */ void flushCacheStat() { synchronized (mCacheStatLock) { if (!mCacheStat.isEmpty()) { long start = System.currentTimeMillis(); for (Map.Entry<String, CacheAccessStat> entry : mCacheStat.entrySet()) { mCacheDatabase.execSQL("UPDATE cache SET " + CACHE_LASTACCESSTIME_COL + "=" + entry.getValue().mLastAccessTime + "," + CACHE_ACCESSCOUNTER_COL + "=" + entry.getValue().mCacheAccessCounter + "," + CACHE_WEIGHT_COL + "=" + entry.getValue().mWeight + " WHERE url = ?", new String[] { entry.getKey() } ); } mCacheStat.clear(); } } } /** * Get a cache item. * Loading @@ -631,7 +791,7 @@ public class WebViewDatabase { Cursor cursor = null; final String query = "SELECT filepath, lastmodify, etag, expires, " + "expiresstring, mimetype, encoding, httpstatus, location, contentlength, " + "contentdisposition, crossdomain FROM cache WHERE url = ?"; + "contentdisposition, crossdomain, accesscounter FROM cache WHERE url = ?"; try { cursor = mCacheDatabase.rawQuery(query, new String[] { url }); if (cursor.moveToFirst()) { Loading @@ -648,6 +808,8 @@ public class WebViewDatabase { ret.contentLength = cursor.getLong(9); ret.contentdisposition = cursor.getString(10); ret.crossDomain = cursor.getString(11); ret.accessCounter = cursor.getInt(12); updateCacheStat(url, ret); return ret; } } catch (IllegalStateException e) { Loading @@ -667,8 +829,10 @@ public class WebViewDatabase { if (url == null || mCacheDatabase == null) { return; } mCacheDatabase.execSQL("DELETE FROM cache WHERE url = ?", new String[] { url }); synchronized (mCacheStatLock) { mCacheStat.remove(url); } } /** Loading Loading @@ -697,6 +861,18 @@ public class WebViewDatabase { mCacheInserter.bind(mCacheContentDispositionColIndex, c.contentdisposition); mCacheInserter.bind(mCacheCrossDomainColIndex, c.crossDomain); CacheAccessStat cacheStat = updateCacheStat(url, c); if (cacheStat == null) { mCacheInserter.bind(mCacheLastAccessTimeIndex, System.currentTimeMillis()); mCacheInserter.bind(mCacheAccessCounterIndex, c.accessCounter+1); mCacheInserter.bind(mCacheWeightIndex, 0); } else { mCacheInserter.bind(mCacheLastAccessTimeIndex, cacheStat.mLastAccessTime); mCacheInserter.bind(mCacheAccessCounterIndex, cacheStat.mCacheAccessCounter); mCacheInserter.bind(mCacheWeightIndex, cacheStat.mWeight); } mCacheInserter.execute(); } Loading @@ -709,6 +885,9 @@ public class WebViewDatabase { } mCacheDatabase.delete("cache", null, null); synchronized (mCacheStatLock) { mCacheStat.clear(); } } boolean hasCache() { Loading Loading @@ -753,7 +932,13 @@ public class WebViewDatabase { List<String> trimCache(long amount) { ArrayList<String> pathList = new ArrayList<String>(100); Cursor cursor = null; final String query = "SELECT contentlength, filepath FROM cache ORDER BY expires ASC"; flushCacheStat(); if (CACHE_EVICT_EXPIRED!=0) { mCacheDatabase.execSQL("UPDATE cache SET " + CACHE_WEIGHT_COL + "=" + CACHE_LASTACCESSTIME_COL + " WHERE " + CACHE_EXPIRES_COL + "<=" + System.currentTimeMillis() + " AND " + CACHE_EXPIRES_COL + "!=0"); } final String query = "SELECT contentlength, filepath FROM cache ORDER BY " + CACHE_ORDER_BY + " ASC"; try { cursor = mCacheDatabase.rawQuery(query, null); if (cursor.moveToFirst()) { Loading Loading
core/java/android/webkit/BrowserFrame.java +3 −2 Original line number Diff line number Diff line /* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2010, Code Aurora Forum. All rights reserved. * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -30,6 +30,7 @@ import android.net.WebAddress; import android.net.http.SslCertificate; import android.os.Handler; import android.os.Message; import android.os.SystemProperties; import android.provider.OpenableColumns; import android.util.Log; import android.util.TypedValue; Loading Loading @@ -195,7 +196,7 @@ class BrowserFrame extends Handler { ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); if (am.getMemoryClass() > 16) { sJavaBridge.setCacheSize(8 * 1024 * 1024); sJavaBridge.setCacheSize(SystemProperties.getInt("webkit.cache.size", 8 * 1024 * 1024)); } else { sJavaBridge.setCacheSize(4 * 1024 * 1024); } Loading
core/java/android/webkit/CacheManager.java +14 −3 Original line number Diff line number Diff line /* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -20,6 +21,7 @@ import android.content.Context; import android.net.http.AndroidHttpClient; import android.net.http.Headers; import android.os.FileUtils; import android.os.SystemProperties; import android.util.Log; import java.io.File; import java.io.FileInputStream; Loading Loading @@ -57,11 +59,14 @@ public final class CacheManager { private static final String MAX_AGE = "max-age"; private static final String MANIFEST_MIME = "text/cache-manifest"; private static long CACHE_THRESHOLD = 6 * 1024 * 1024; private static long CACHE_TRIM_AMOUNT = 2 * 1024 * 1024; private static final long CACHE_THRESHOLD_DEF = 6 * 1024 * 1024; private static final long CACHE_TRIM_AMOUNT_DEF = 2 * 1024 * 1024; private static long CACHE_THRESHOLD = CACHE_THRESHOLD_DEF; private static long CACHE_TRIM_AMOUNT = CACHE_TRIM_AMOUNT_DEF; // Limit the maximum cache file size to half of the normal capacity static long CACHE_MAX_SIZE = (CACHE_THRESHOLD - CACHE_TRIM_AMOUNT) / 2; static long CACHE_MAX_SIZE = (CACHE_THRESHOLD_DEF - CACHE_TRIM_AMOUNT_DEF) / 2; private static boolean mDisabled; Loading Loading @@ -100,6 +105,7 @@ public final class CacheManager { String encoding; String contentdisposition; String crossDomain; int accessCounter; // these fields are NOT saved to the database InputStream inStream; Loading Loading @@ -181,6 +187,10 @@ public final class CacheManager { removeAllCacheFiles(); mClearCacheOnInit = false; } CACHE_THRESHOLD = SystemProperties.getLong("nw.cache.threshold", CACHE_THRESHOLD_DEF); CACHE_TRIM_AMOUNT = SystemProperties.getLong("nw.cache.trimamount", CACHE_TRIM_AMOUNT_DEF); CACHE_MAX_SIZE = (CACHE_THRESHOLD - CACHE_TRIM_AMOUNT) / 2; } /** Loading Loading @@ -545,6 +555,7 @@ public final class CacheManager { } static void trimCacheIfNeeded() { mDataBase.flushCacheStat(); if (mDataBase.getCacheTotalSize() > CACHE_THRESHOLD) { List<String> pathList = mDataBase.trimCache(CACHE_TRIM_AMOUNT); int size = pathList.size(); Loading
core/java/android/webkit/WebViewDatabase.java +189 −4 Original line number Diff line number Diff line /* * Copyright (C) 2007 The Android Open Source Project * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -20,7 +21,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.HashMap; import java.util.Map.Entry; import android.content.ContentValues; Loading @@ -30,6 +33,7 @@ import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteStatement; import android.os.SystemProperties; import android.util.Log; import android.webkit.CookieManager.Cookie; import android.webkit.CacheManager.CacheResult; Loading @@ -51,10 +55,11 @@ public class WebViewDatabase { // 7 -> 8 Move cache to its own db // 8 -> 9 Store both scheme and host when storing passwords // 9 -> 10 Update httpauth table UNIQUE private static final int CACHE_DATABASE_VERSION = 4; private static final int CACHE_DATABASE_VERSION = 5; // 1 -> 2 Add expires String // 2 -> 3 Add content-disposition // 3 -> 4 Add crossdomain (For x-permitted-cross-domain-policies header) // 4 -> 5 Add last-acces-time, access-counter, weight private static WebViewDatabase mInstance = null; Loading Loading @@ -129,6 +134,12 @@ public class WebViewDatabase { private static final String CACHE_CROSSDOMAIN_COL = "crossdomain"; private static final String CACHE_LASTACCESSTIME_COL = "lastaccesstime"; private static final String CACHE_ACCESSCOUNTER_COL = "accesscounter"; private static final String CACHE_WEIGHT_COL = "weight"; // column id strings for "password" table private static final String PASSWORD_HOST_COL = "host"; Loading Loading @@ -170,9 +181,104 @@ public class WebViewDatabase { private static int mCacheContentLengthColIndex; private static int mCacheContentDispositionColIndex; private static int mCacheCrossDomainColIndex; private static int mCacheLastAccessTimeIndex; private static int mCacheAccessCounterIndex; private static int mCacheWeightIndex; private static int mCacheTransactionRefcount; private static final int CACHE_STAT_ID_OTHER = 0; private static final int CACHE_STAT_ID_HTML = 1; private static final int CACHE_STAT_ID_CSS = 2; private static final int CACHE_STAT_ID_JS = 3; private static final int CACHE_STAT_ID_IMAGE = 4; private static final String CACHE_ORDER_BY_DEF = CACHE_EXPIRES_COL; private static String CACHE_ORDER_BY = CACHE_ORDER_BY_DEF; private static final int CACHE_EVICT_EXPIRED_DEF = 0; private static final long CACHE_PRIO_ADVANCE_STEP_DEF = 0; private static final long CACHE_WEIGHT_ADVANCE_STEP_DEF = 0; private static int CACHE_EVICT_EXPIRED = CACHE_EVICT_EXPIRED_DEF; private static long CACHE_ADVANCE_STEP_PRIO = CACHE_PRIO_ADVANCE_STEP_DEF; private static long CACHE_ADVANCE_STEP_WEIGHT = CACHE_WEIGHT_ADVANCE_STEP_DEF; private static class CacheAccessStat { long mLastAccessTime = 0; int mCacheAccessCounter = 0; int mCacheItemPriority = 0; long mContentLength = 0; long mWeight = 0; public CacheAccessStat(CacheResult c) { mCacheAccessCounter = c.accessCounter; mCacheItemPriority = getCacheItemPriority(c.getMimeType()); mContentLength = c.getContentLength(); hit(); } public void hit() { mCacheAccessCounter++; mLastAccessTime = System.currentTimeMillis(); mWeight = mLastAccessTime + CACHE_ADVANCE_STEP_PRIO * mCacheItemPriority; mWeight += CACHE_ADVANCE_STEP_WEIGHT * normalize(mContentLength/mCacheAccessCounter); } int getCacheStatId(String mimeType) { if (mimeType.contains("image")) { return CACHE_STAT_ID_IMAGE; } if (mimeType.contains("javascript") || mimeType.contains("js")) { return CACHE_STAT_ID_JS; } if (mimeType.contains("css")) { return CACHE_STAT_ID_CSS; } if (mimeType.contains("html")) { return CACHE_STAT_ID_HTML; } return CACHE_STAT_ID_OTHER; } /** * Get resource priority */ int getCacheItemPriority(String mimeType) { int id = getCacheStatId(mimeType); switch (id) { case CACHE_STAT_ID_CSS: case CACHE_STAT_ID_HTML: return 2; case CACHE_STAT_ID_JS: return 1; case CACHE_STAT_ID_IMAGE: return 0; } return -1; } int normalize(long i) { int normalized = 0; if ((i & (i - 1)) != 0) { normalized += 1; } for (int index = 16; index >= 2; index = index/2 ) { if ((i >> index) != 0) { normalized += index; i >>= index; } } if ((i >> 1) != 0) { normalized += 1; } return (32 - normalized); } } private final Object mCacheStatLock = new Object(); private static HashMap<String, CacheAccessStat> mCacheStat = new HashMap<String, CacheAccessStat>(); private WebViewDatabase() { // Singleton only, use getInstance() } Loading @@ -180,6 +286,12 @@ public class WebViewDatabase { public static synchronized WebViewDatabase getInstance(Context context) { if (mInstance == null) { mInstance = new WebViewDatabase(); CACHE_EVICT_EXPIRED = SystemProperties.getInt("nw.cache.evictexpired", CACHE_EVICT_EXPIRED_DEF); CACHE_ADVANCE_STEP_PRIO = SystemProperties.getLong("nw.cache.prioadvstep", CACHE_PRIO_ADVANCE_STEP_DEF); CACHE_ADVANCE_STEP_WEIGHT = SystemProperties.getLong("nw.cache.weightadvstep", CACHE_WEIGHT_ADVANCE_STEP_DEF); CACHE_ORDER_BY = SystemProperties.get("nw.cache.orderby", CACHE_ORDER_BY_DEF); try { mDatabase = context .openOrCreateDatabase(DATABASE_FILE, 0, null); Loading Loading @@ -275,6 +387,12 @@ public class WebViewDatabase { .getColumnIndex(CACHE_CONTENTDISPOSITION_COL); mCacheCrossDomainColIndex = mCacheInserter .getColumnIndex(CACHE_CROSSDOMAIN_COL); mCacheLastAccessTimeIndex = mCacheInserter .getColumnIndex(CACHE_LASTACCESSTIME_COL); mCacheAccessCounterIndex = mCacheInserter .getColumnIndex(CACHE_ACCESSCOUNTER_COL); mCacheWeightIndex = mCacheInserter .getColumnIndex(CACHE_WEIGHT_COL); } } Loading Loading @@ -385,6 +503,9 @@ public class WebViewDatabase { + CACHE_LOCATION_COL + " TEXT, " + CACHE_CONTENTLENGTH_COL + " INTEGER, " + CACHE_CONTENTDISPOSITION_COL + " TEXT, " + CACHE_CROSSDOMAIN_COL + " TEXT," + CACHE_LASTACCESSTIME_COL + " INTEGER," + CACHE_ACCESSCOUNTER_COL + " INTEGER," + CACHE_WEIGHT_COL + " INTEGER," + " UNIQUE (" + CACHE_URL_COL + ") ON CONFLICT REPLACE);"); mCacheDatabase.execSQL("CREATE INDEX cacheUrlIndex ON cache (" + CACHE_URL_COL + ")"); Loading Loading @@ -617,6 +738,45 @@ public class WebViewDatabase { return false; } /** * Update cache statistics */ CacheAccessStat updateCacheStat(String url, CacheResult c) { if (c.expires != 0) { CacheAccessStat cacheStat; synchronized (mCacheStatLock) { cacheStat = mCacheStat.get(url); if (cacheStat == null) { cacheStat = new CacheAccessStat(c); mCacheStat.put( url , cacheStat); } else { cacheStat.hit(); } } return cacheStat; } return null; } /** * Flush cache statistics */ void flushCacheStat() { synchronized (mCacheStatLock) { if (!mCacheStat.isEmpty()) { long start = System.currentTimeMillis(); for (Map.Entry<String, CacheAccessStat> entry : mCacheStat.entrySet()) { mCacheDatabase.execSQL("UPDATE cache SET " + CACHE_LASTACCESSTIME_COL + "=" + entry.getValue().mLastAccessTime + "," + CACHE_ACCESSCOUNTER_COL + "=" + entry.getValue().mCacheAccessCounter + "," + CACHE_WEIGHT_COL + "=" + entry.getValue().mWeight + " WHERE url = ?", new String[] { entry.getKey() } ); } mCacheStat.clear(); } } } /** * Get a cache item. * Loading @@ -631,7 +791,7 @@ public class WebViewDatabase { Cursor cursor = null; final String query = "SELECT filepath, lastmodify, etag, expires, " + "expiresstring, mimetype, encoding, httpstatus, location, contentlength, " + "contentdisposition, crossdomain FROM cache WHERE url = ?"; + "contentdisposition, crossdomain, accesscounter FROM cache WHERE url = ?"; try { cursor = mCacheDatabase.rawQuery(query, new String[] { url }); if (cursor.moveToFirst()) { Loading @@ -648,6 +808,8 @@ public class WebViewDatabase { ret.contentLength = cursor.getLong(9); ret.contentdisposition = cursor.getString(10); ret.crossDomain = cursor.getString(11); ret.accessCounter = cursor.getInt(12); updateCacheStat(url, ret); return ret; } } catch (IllegalStateException e) { Loading @@ -667,8 +829,10 @@ public class WebViewDatabase { if (url == null || mCacheDatabase == null) { return; } mCacheDatabase.execSQL("DELETE FROM cache WHERE url = ?", new String[] { url }); synchronized (mCacheStatLock) { mCacheStat.remove(url); } } /** Loading Loading @@ -697,6 +861,18 @@ public class WebViewDatabase { mCacheInserter.bind(mCacheContentDispositionColIndex, c.contentdisposition); mCacheInserter.bind(mCacheCrossDomainColIndex, c.crossDomain); CacheAccessStat cacheStat = updateCacheStat(url, c); if (cacheStat == null) { mCacheInserter.bind(mCacheLastAccessTimeIndex, System.currentTimeMillis()); mCacheInserter.bind(mCacheAccessCounterIndex, c.accessCounter+1); mCacheInserter.bind(mCacheWeightIndex, 0); } else { mCacheInserter.bind(mCacheLastAccessTimeIndex, cacheStat.mLastAccessTime); mCacheInserter.bind(mCacheAccessCounterIndex, cacheStat.mCacheAccessCounter); mCacheInserter.bind(mCacheWeightIndex, cacheStat.mWeight); } mCacheInserter.execute(); } Loading @@ -709,6 +885,9 @@ public class WebViewDatabase { } mCacheDatabase.delete("cache", null, null); synchronized (mCacheStatLock) { mCacheStat.clear(); } } boolean hasCache() { Loading Loading @@ -753,7 +932,13 @@ public class WebViewDatabase { List<String> trimCache(long amount) { ArrayList<String> pathList = new ArrayList<String>(100); Cursor cursor = null; final String query = "SELECT contentlength, filepath FROM cache ORDER BY expires ASC"; flushCacheStat(); if (CACHE_EVICT_EXPIRED!=0) { mCacheDatabase.execSQL("UPDATE cache SET " + CACHE_WEIGHT_COL + "=" + CACHE_LASTACCESSTIME_COL + " WHERE " + CACHE_EXPIRES_COL + "<=" + System.currentTimeMillis() + " AND " + CACHE_EXPIRES_COL + "!=0"); } final String query = "SELECT contentlength, filepath FROM cache ORDER BY " + CACHE_ORDER_BY + " ASC"; try { cursor = mCacheDatabase.rawQuery(query, null); if (cursor.moveToFirst()) { Loading