From 79e82b7ba72a7278911edf0dd7b03c65c4ec0e9d Mon Sep 17 00:00:00 2001 From: Andrei Popescu Date: Mon, 27 Jul 2009 12:01:59 +0100 Subject: [PATCH] Refactor the WebStorage size management: - Abandon the Quota UI: it does not make sense to ask the users to decide individual database quota increases. It is unlikely anyone will be able to make a meaningul decision. - Introduce a global limit for all WebStorage content. This is shared between Database and AppCache. - Make the quota increase decision automatic - Treat out-of-space situations by creaying a system notification (TODO). --- src/com/android/browser/BrowserActivity.java | 53 ++-- src/com/android/browser/BrowserSettings.java | 41 +-- src/com/android/browser/PermissionDialog.java | 175 ------------- src/com/android/browser/WebStorageSizeManager.java | 282 +++++++++++++++++++++ ...ts.java => WebStorageSizeManagerUnitTests.java} | 50 ++-- 5 files changed, 339 insertions(+), 262 deletions(-) delete mode 100644 src/com/android/browser/PermissionDialog.java create mode 100644 src/com/android/browser/WebStorageSizeManager.java rename tests/src/com/android/browser/{BrowserSettingsUnitTests.java => WebStorageSizeManagerUnitTests.java} (52%) diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index d148c0a..7f40494 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -165,8 +165,6 @@ public class BrowserActivity extends Activity private SensorManager mSensorManager = null; - private WebStorage.QuotaUpdater mWebStorageQuotaUpdater = null; - // These are single-character shortcuts for searching popular sources. private static final int SHORTCUT_INVALID = 0; private static final int SHORTCUT_GOOGLE_SEARCH = 1; @@ -3850,36 +3848,38 @@ public class BrowserActivity extends Activity } /** - * The origin has exceeded it's database quota. + * The origin has exceeded its database quota. * @param url the URL that exceeded the quota * @param databaseIdentifier the identifier of the database on * which the transaction that caused the quota overflow was run * @param currentQuota the current quota for the origin. + * @param totalUsedQuota is the sum of all origins' quota. * @param quotaUpdater The callback to run when a decision to allow or * deny quota has been made. Don't forget to call this! */ @Override public void onExceededDatabaseQuota(String url, - String databaseIdentifier, long currentQuota, + String databaseIdentifier, long currentQuota, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) { - if(LOGV_ENABLED) { - Log.v(LOGTAG, - "BrowserActivity received onExceededDatabaseQuota for " - + url + - ":" - + databaseIdentifier + - "(current quota: " - + currentQuota + - ")"); - } - mWebStorageQuotaUpdater = quotaUpdater; - String DIALOG_PACKAGE = "com.android.browser"; - String DIALOG_CLASS = DIALOG_PACKAGE + ".PermissionDialog"; - Intent intent = new Intent(); - intent.setClassName(DIALOG_PACKAGE, DIALOG_CLASS); - intent.putExtra(PermissionDialog.PARAM_ORIGIN, url); - intent.putExtra(PermissionDialog.PARAM_QUOTA, currentQuota); - startActivityForResult(intent, WEBSTORAGE_QUOTA_DIALOG); + mSettings.getWebStorageSizeManager().onExceededDatabaseQuota( + url, databaseIdentifier, currentQuota, totalUsedQuota, + quotaUpdater); + } + + /** + * The Application Cache has exceeded its max size. + * @param spaceNeeded is the amount of disk space that would be needed + * in order for the last appcache operation to succeed. + * @param totalUsedQuota is the sum of all origins' quota. + * @param quotaUpdater A callback to inform the WebCore thread that a new + * app cache size is available. This callback must always be executed at + * some point to ensure that the sleeping WebCore thread is woken up. + */ + @Override + public void onReachedMaxAppCacheSize(long spaceNeeded, + long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) { + mSettings.getWebStorageSizeManager().onReachedMaxAppCacheSize( + spaceNeeded, totalUsedQuota, quotaUpdater); } /* Adds a JavaScript error message to the system log. @@ -4616,14 +4616,6 @@ public class BrowserActivity extends Activity } } break; - case WEBSTORAGE_QUOTA_DIALOG: - long currentQuota = 0; - if (resultCode == RESULT_OK && intent != null) { - currentQuota = intent.getLongExtra( - PermissionDialog.PARAM_QUOTA, currentQuota); - } - mWebStorageQuotaUpdater.updateQuota(currentQuota); - break; default: break; } @@ -5169,7 +5161,6 @@ public class BrowserActivity extends Activity final static int COMBO_PAGE = 1; final static int DOWNLOAD_PAGE = 2; final static int PREFERENCES_PAGE = 3; - final static int WEBSTORAGE_QUOTA_DIALOG = 4; // the frenquency of checking whether system memory is low final static int CHECK_MEMORY_INTERVAL = 30000; // 30 seconds diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java index d2371cd..3074d2b 100644 --- a/src/com/android/browser/BrowserSettings.java +++ b/src/com/android/browser/BrowserSettings.java @@ -25,7 +25,6 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; -import android.os.StatFs; import android.webkit.CookieManager; import android.webkit.WebView; import android.webkit.WebViewDatabase; @@ -79,6 +78,7 @@ class BrowserSettings extends Observable { private boolean appCacheEnabled = true; private String appCachePath; // default value set in loadFromDb(). private long appCacheMaxSize = Long.MAX_VALUE; + private WebStorageSizeManager webStorageSizeManager; private boolean domStorageEnabled = true; private String jsFlags = ""; @@ -238,7 +238,9 @@ class BrowserSettings extends Observable { // Set the default value for the Application Caches path. appCachePath = ctx.getDir("appcache", 0).getPath(); // Determine the maximum size of the application cache. - appCacheMaxSize = getAppCacheMaxSize(); + webStorageSizeManager = WebStorageSizeManager.getInstance(appCachePath, + ctx); + appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize(); // Set the default value for the Database path. databasePath = ctx.getDir("databases", 0).getPath(); @@ -363,6 +365,10 @@ class BrowserSettings extends Observable { return jsFlags; } + public WebStorageSizeManager getWebStorageSizeManager() { + return webStorageSizeManager; + } + public void setHomePage(Context context, String url) { Editor ed = PreferenceManager. getDefaultSharedPreferences(context).edit(); @@ -532,6 +538,8 @@ class BrowserSettings extends Observable { true); // reset homeUrl setHomePage(ctx, getFactoryResetHomeUrl(ctx)); + // reset appcache max size + appCacheMaxSize = webStorageSizeManager.getAppCacheMaxSize(); } private String getFactoryResetHomeUrl(Context context) { @@ -543,35 +551,6 @@ class BrowserSettings extends Observable { return url; } - private long getAppCacheMaxSize() { - StatFs dataPartition = new StatFs(appCachePath); - long freeSpace = dataPartition.getAvailableBlocks() - * dataPartition.getBlockSize(); - long fileSystemSize = dataPartition.getBlockCount() - * dataPartition.getBlockSize(); - return calculateAppCacheMaxSize(fileSystemSize, freeSpace); - } - - /*package*/ static long calculateAppCacheMaxSize(long fileSystemSizeBytes, - long freeSpaceBytes) { - if (fileSystemSizeBytes <= 0 - || freeSpaceBytes <= 0 - || freeSpaceBytes > fileSystemSizeBytes) { - return 0; - } - - long fileSystemSizeRatio = - 4 << ((int) Math.floor(Math.log10(fileSystemSizeBytes / (1024 * 1024)))); - long maxSizeBytes = (long) Math.min(Math.floor(fileSystemSizeBytes / fileSystemSizeRatio), - Math.floor(freeSpaceBytes / 4)); - // Round maxSizeBytes up to a multiple of 512KB (except when freeSpaceBytes < 1MB). - long maxSizeStepBytes = 512 * 1024; - if (freeSpaceBytes < maxSizeStepBytes * 2) { - return 0; - } - return (maxSizeStepBytes * ((maxSizeBytes / maxSizeStepBytes) + 1)); - } - // Private constructor that does nothing. private BrowserSettings() { } diff --git a/src/com/android/browser/PermissionDialog.java b/src/com/android/browser/PermissionDialog.java deleted file mode 100644 index b71261a..0000000 --- a/src/com/android/browser/PermissionDialog.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.browser; - -import android.app.Activity; -import android.app.Dialog; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -/** - * Permission dialog for HTML5 - * @hide - */ -public class PermissionDialog extends Activity { - - private static final String TAG = "PermissionDialog"; - public static final String PARAM_ORIGIN = "origin"; - public static final String PARAM_QUOTA = "quota"; - - private String mWebStorageOrigin; - private long mWebStorageQuota = 0; - private int mNotification = 0; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - getParameters(); - setupDialog(); - } - - private void getParameters() { - Intent intent = getIntent(); - mWebStorageOrigin = intent.getStringExtra(PARAM_ORIGIN); - mWebStorageQuota = intent.getLongExtra(PARAM_QUOTA, 0); - } - - private void setupDialog() { - requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.permission_dialog); - - setIcon(R.id.icon, android.R.drawable.ic_popup_disk_full); - setText(R.id.dialog_title, R.string.query_storage_quota_prompt); - setText(R.id.dialog_message, R.string.query_storage_quota_message); - setCharSequence(R.id.origin, mWebStorageOrigin); - - setupButton(R.id.button_allow, R.string.permission_button_allow, - new View.OnClickListener() { - public void onClick(View v) { allow(); } - }); - setupButton(R.id.button_alwaysdeny, R.string.permission_button_alwaysdeny, - new View.OnClickListener() { - public void onClick(View v) { alwaysdeny(); } - }); - setupButton(R.id.button_deny, R.string.permission_button_deny, - new View.OnClickListener() { - public void onClick(View v) { deny(); } - }); - } - - private void setText(int viewID, int stringID) { - setCharSequence(viewID, getString(stringID)); - } - - private void setCharSequence(int viewID, CharSequence string) { - View view = findViewById(viewID); - if (view == null) { - return; - } - view.setVisibility(View.VISIBLE); - TextView textView = (TextView) view; - textView.setText(string); - } - - private void setIcon(int viewID, int imageID) { - View view = findViewById(viewID); - if (view == null) { - return; - } - view.setVisibility(View.VISIBLE); - ImageView icon = (ImageView) view; - icon.setImageResource(imageID); - } - - private void setupButton(int viewID, int stringID, - View.OnClickListener listener) { - View view = findViewById(viewID); - if (view == null) { - return; - } - setText(viewID, stringID); - view.setOnClickListener(listener); - } - - private void useNextQuota() { - CharSequence[] values = getResources().getTextArray( - R.array.webstorage_quota_entries_values); - for (int i=0; i mWebStorageQuota) { - mWebStorageQuota = value; - break; - } - } - } - - private void allow() { - // If somehow there is no "next quota" in the ladder, - // we'll add 1MB anyway. - mWebStorageQuota += 1024*1024; - useNextQuota(); - mNotification = R.string.webstorage_notification; - closeDialog(); - } - - private void alwaysdeny() { - // Setting the quota to 0 will prevent any new data to be - // added, but the existing data will not be deleted. - mWebStorageQuota = 0; - mNotification = R.string.webstorage_notification; - closeDialog(); - } - - private void deny() { - closeDialog(); - } - - private void closeDialog() { - Intent intent = new Intent(); - intent.putExtra(PARAM_QUOTA, mWebStorageQuota); - setResult(RESULT_OK, intent); - showToast(); - finish(); - } - - private void showToast() { - if (mNotification != 0) { - Toast toast = Toast.makeText(this, mNotification, Toast.LENGTH_LONG); - toast.setGravity(Gravity.BOTTOM, 0, 0); - toast.show(); - } - } - - public boolean dispatchKeyEvent(KeyEvent event) { - if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK) - && (event.getAction() == KeyEvent.ACTION_DOWN)) { - closeDialog(); - return true; // event consumed - } - return super.dispatchKeyEvent(event); - } - -} diff --git a/src/com/android/browser/WebStorageSizeManager.java b/src/com/android/browser/WebStorageSizeManager.java new file mode 100644 index 0000000..e524f4c --- /dev/null +++ b/src/com/android/browser/WebStorageSizeManager.java @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser; + +import android.content.Context; +import android.os.StatFs; +import android.util.Log; +import android.webkit.WebStorage; + +import java.io.File; +import java.util.Set; + + +/** + * Package level class for managing the disk size consumed by the WebDatabase + * and ApplicationCaches APIs (henceforth called Web storage). + * + * Currently, the situation on the WebKit side is as follows: + * - WebDatabase enforces a quota for each origin. + * - Session/LocalStorage do not enforce any disk limits. + * - ApplicationCaches enforces a maximum size for all origins. + * + * The WebStorageSizeManager maintains a global limit for the disk space + * consumed by the WebDatabase and ApplicationCaches. As soon as WebKit will + * have a limit for Session/LocalStorage, this class will manage the space used + * by those APIs as well. + * + * The global limit is computed as a function of the size of the partition where + * these APIs store their data (they must store it on the same partition for + * this to work) and the size of the available space on that partition. + * The global limit is not subject to user configuration but we do provide + * a debug-only setting. + * TODO(andreip): implement the debug setting. + * + * The size of the disk space used for Web storage is initially divided between + * WebDatabase and ApplicationCaches as follows: + * + * 75% for WebDatabase + * 25% for ApplicationCaches + * + * When an origin's database usage reaches its current quota, WebKit invokes + * the following callback function: + * - exceededDatabaseQuota(Frame* frame, const String& database_name); + * Note that the default quota for a new origin is 0, so we will receive the + * 'exceededDatabaseQuota' callback before a new origin gets the chance to + * create its first database. + * + * When the total ApplicationCaches usage reaches its current quota, WebKit + * invokes the following callback function: + * - void reachedMaxAppCacheSize(int64_t spaceNeeded); + * + * The WebStorageSizeManager's main job is to respond to the above two callbacks + * by inspecting the amount of unused Web storage quota (i.e. global limit - + * sum of all other origins' quota) and deciding if a quota increase for the + * out-of-space origin is allowed or not. + * + * The default quota for an origin is min(ORIGIN_DEFAULT_QUOTA, unused_quota). + * Quota increases are done in steps, where the increase step is + * min(QUOTA_INCREASE_STEP, unused_quota). + * + * This approach has the drawback that space may remain unused if there + * are many websites that store a lot less content than ORIGIN_DEFAULT_QUOTA. + * We deal with this by picking a value for ORIGIN_DEFAULT_QUOTA that is smaller + * than what the HTML 5 spec recommends. At the same time, picking a very small + * value for ORIGIN_DEFAULT_QUOTA may create performance problems since it's + * more likely for origins to have to rollback and restart transactions as a + * result of reaching the quota more often. + * + * When all the Web storage space is used, the WebStorageSizeManager creates + * a system notification that will guide the user to the WebSettings UI. There, + * the user can free some of the Web storage space by deleting all the data used + * by an origin. + * TODO(andreip): implement the notification. + */ +class WebStorageSizeManager { + // Logging flags. + private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED; + private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED; + private final static String LOGTAG = "browser"; + // The default quota value for an origin. + private final static long ORIGIN_DEFAULT_QUOTA = 4 * 1024 * 1024; // 4MB + // The default value for quota increases. + private final static long QUOTA_INCREASE_STEP = 2 * 1024 * 1024; // 2MB + // The name of the application cache file. Keep in sync with + // WebCore/loader/appcache/ApplicationCacheStorage.cpp + private final static String APPCACHE_FILE = "ApplicationCache.db"; + // The WebStorageSizeManager singleton. + private static WebStorageSizeManager mManager; + // The application context. + private Context mContext; + // The global Web storage limit. + private long mGlobalLimit; + // The maximum size of the application cache file. + private long mAppCacheMaxSize; + + /** + * Factory method. + * @param path is a path on the partition where the app cache data is kept. + * @param ctx is the browser application context. + * @param storage is the WebStorage singleton. + * + */ + public static WebStorageSizeManager getInstance(String appCachePath, + Context ctx) { + if (mManager == null) { + mManager = new WebStorageSizeManager(appCachePath, ctx); + } + return mManager; + } + + /** + * Returns the maximum size of the application cache. + */ + public long getAppCacheMaxSize() { + return mAppCacheMaxSize; + } + + /** + * The origin has exceeded its database quota. + * @param url the URL that exceeded the quota + * @param databaseIdentifier the identifier of the database on + * which the transaction that caused the quota overflow was run + * @param currentQuota the current quota for the origin. + * @param totalUsedQuota is the sum of all origins' quota. + * @param quotaUpdater The callback to run when a decision to allow or + * deny quota has been made. Don't forget to call this! + */ + public void onExceededDatabaseQuota(String url, + String databaseIdentifier, long currentQuota, long totalUsedQuota, + WebStorage.QuotaUpdater quotaUpdater) { + if(LOGV_ENABLED) { + Log.v(LOGTAG, + "Received onExceededDatabaseQuota for " + + url + + ":" + + databaseIdentifier + + "(current quota: " + + currentQuota + + ")"); + } + long totalUnusedQuota = mGlobalLimit - totalUsedQuota - mAppCacheMaxSize; + + if (totalUnusedQuota < QUOTA_INCREASE_STEP) { + // There definitely isn't any more space. Fire notifications + // and exit. + scheduleOutOfSpaceNotification(); + quotaUpdater.updateQuota(currentQuota); + if(LOGV_ENABLED) { + Log.v(LOGTAG, "onExceededDatabaseQuota: out of space."); + } + return; + } + // We have enough space inside mGlobalLimit. + long newOriginQuota = currentQuota; + if (newOriginQuota == 0) { + // This is a new origin. It wants an initial quota. It is guaranteed + // to get at least ORIGIN_INCREASE_STEP bytes. + newOriginQuota = + Math.min(ORIGIN_DEFAULT_QUOTA, totalUnusedQuota); + } else { + // This is an origin we have seen before. It wants a quota + // increase. + newOriginQuota += + Math.min(QUOTA_INCREASE_STEP, totalUnusedQuota); + } + quotaUpdater.updateQuota(newOriginQuota); + + if(LOGV_ENABLED) { + Log.v(LOGTAG, "onExceededDatabaseQuota set new quota to " + + newOriginQuota); + } + } + + /** + * The Application Cache has exceeded its max size. + * @param spaceNeeded is the amount of disk space that would be needed + * in order for the last appcache operation to succeed. + * @param totalUsedQuota is the sum of all origins' quota. + * @param quotaUpdater A callback to inform the WebCore thread that a new + * app cache size is available. This callback must always be executed at + * some point to ensure that the sleeping WebCore thread is woken up. + */ + public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota, + WebStorage.QuotaUpdater quotaUpdater) { + if(LOGV_ENABLED) { + Log.v(LOGTAG, "Received onReachedMaxAppCacheSize with spaceNeeded " + + spaceNeeded + " bytes."); + } + + long totalUnusedQuota = mGlobalLimit - totalUsedQuota - mAppCacheMaxSize; + + if (totalUnusedQuota < spaceNeeded) { + // There definitely isn't any more space. Fire notifications + // and exit. + scheduleOutOfSpaceNotification(); + quotaUpdater.updateQuota(0); + if(LOGV_ENABLED) { + Log.v(LOGTAG, "onReachedMaxAppCacheSize: out of space."); + } + return; + } + // There is enough space to accommodate spaceNeeded bytes. + mAppCacheMaxSize += spaceNeeded; + quotaUpdater.updateQuota(mAppCacheMaxSize); + + if(LOGV_ENABLED) { + Log.v(LOGTAG, "onReachedMaxAppCacheSize set new max size to " + + mAppCacheMaxSize); + } + } + + // Computes the global limit as a function of the size of the data + // partition and the amount of free space on that partition. + private long getGlobalLimit(String path) { + StatFs dataPartition = new StatFs(path); + long freeSpace = dataPartition.getAvailableBlocks() + * dataPartition.getBlockSize(); + long fileSystemSize = dataPartition.getBlockCount() + * dataPartition.getBlockSize(); + return calculateGlobalLimit(fileSystemSize, freeSpace); + } + + // Returns the current size (in bytes) of the application cache file. + private long getCurrentAppCacheSize(String path) { + File file = new File(path + File.separator + APPCACHE_FILE); + return file.length(); + } + + /*package*/ static long calculateGlobalLimit(long fileSystemSizeBytes, + long freeSpaceBytes) { + if (fileSystemSizeBytes <= 0 + || freeSpaceBytes <= 0 + || freeSpaceBytes > fileSystemSizeBytes) { + return 0; + } + + long fileSystemSizeRatio = + 2 << ((int) Math.floor(Math.log10( + fileSystemSizeBytes / (1024 * 1024)))); + long maxSizeBytes = (long) Math.min(Math.floor( + fileSystemSizeBytes / fileSystemSizeRatio), + Math.floor(freeSpaceBytes / 2)); + // Round maxSizeBytes up to a multiple of 1024KB (but only if + // maxSizeBytes > 1MB). + long maxSizeStepBytes = 1024 * 1024; + if (maxSizeBytes < maxSizeStepBytes) { + return 0; + } + long roundingExtra = maxSizeBytes % maxSizeStepBytes == 0 ? 0 : 1; + return (maxSizeStepBytes + * ((maxSizeBytes / maxSizeStepBytes) + roundingExtra)); + } + + // Schedules a system notification that takes the user to the WebSettings + // activity when clicked. + private void scheduleOutOfSpaceNotification() { + // TODO(andreip): implement. + } + // Private ctor. + private WebStorageSizeManager(String appCachePath, Context ctx) { + mContext = ctx; + mGlobalLimit = getGlobalLimit(appCachePath); + // The initial max size of the app cache is either 25% of the global + // limit or the current size of the app cache file, whichever is bigger. + mAppCacheMaxSize = Math.max(mGlobalLimit / 4, + getCurrentAppCacheSize(appCachePath)); + } +} \ No newline at end of file diff --git a/tests/src/com/android/browser/BrowserSettingsUnitTests.java b/tests/src/com/android/browser/WebStorageSizeManagerUnitTests.java similarity index 52% rename from tests/src/com/android/browser/BrowserSettingsUnitTests.java rename to tests/src/com/android/browser/WebStorageSizeManagerUnitTests.java index fdaa5c8..4ba758d 100644 --- a/tests/src/com/android/browser/BrowserSettingsUnitTests.java +++ b/tests/src/com/android/browser/WebStorageSizeManagerUnitTests.java @@ -20,69 +20,69 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.MediumTest; /** - * This is a series of unit tests for the BrowserSettings class. + * This is a series of unit tests for the WebStorageSizeManager class. * */ @MediumTest -public class BrowserSettingsUnitTests extends AndroidTestCase { +public class WebStorageSizeManagerUnitTests extends AndroidTestCase { /** * Test the application caches max size calculator. */ - public void testCalculateAppCacheMaxSize() { + public void testCalculateGlobalLimit() { long fileSystemSize = 78643200; // 75 MB long freeSpaceSize = 25165824; // 24 MB - long maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(6815744, maxSize); // 6.5MB + long maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(12582912, maxSize); // 12MB fileSystemSize = 78643200; // 75 MB freeSpaceSize = 60 * 1024 * 1024; // 60MB - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(9961472, maxSize); // 9.5MB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(19922944, maxSize); // 19MB fileSystemSize = 8589934592L; // 8 GB freeSpaceSize = 4294967296L; // 4 GB - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(268959744L, maxSize); // 256.5 MB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(536870912L, maxSize); // 512 MB fileSystemSize = -14; freeSpaceSize = 21; - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); assertEquals(0, maxSize); fileSystemSize = 100; freeSpaceSize = 101; - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); assertEquals(0, maxSize); fileSystemSize = 3774873; // ~4.2 MB freeSpaceSize = 2560000; // ~2.4 MB - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(1048576, maxSize); // 1 MB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(2097152, maxSize); // 2 MB fileSystemSize = 4404019; // ~4.2 MB freeSpaceSize = 3774873; // ~3.6 MB - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(1048576, maxSize); // 1 MB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(2097152, maxSize); // 2 MB fileSystemSize = 4404019; // ~4.2 MB freeSpaceSize = 4404019; // ~4.2 MB - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(1572864, maxSize); // 1.5 MB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(3145728, maxSize); // 3 MB fileSystemSize = 1048576; // 1 MB freeSpaceSize = 1048575; // 1 MB - 1 byte - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); assertEquals(0, maxSize); - fileSystemSize = 1048576; // 1 MB - freeSpaceSize = 1048576; // 1 MB - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(524288, maxSize); // 512KB - fileSystemSize = 3774873; // ~3.6 MB freeSpaceSize = 2097151; // 2 MB - 1 byte - maxSize = BrowserSettings.calculateAppCacheMaxSize(fileSystemSize, freeSpaceSize); - assertEquals(524288, maxSize); // 512KB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(0, maxSize); + + fileSystemSize = 3774873; // ~3.6 MB + freeSpaceSize = 2097151; // 2 MB + maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize); + assertEquals(0, maxSize); } } -- 2.11.0