Bug 1422160 - Merge cache and site data in about:preferences. r=jaws

This commit removes most of the cache section in about:preferences,
following the UX concept from bug 1421690. This is in the general
interest of de-cluttering privacy preferences and giving users controls
that are easier to understand and use.

The cache size is instead shown in the site data section and the cache
can be cleared using the "Clear Data" button in that same section.

MozReview-Commit-ID: 7PDTDgllFFI

--HG--
extra : rebase_source : 98eea84efb2b90068bf0d106321d8af64afd1f77
This commit is contained in:
Johann Hofmann 2018-02-13 12:33:29 +01:00
parent 9893d30a7f
commit 7b4b3f1ba2
8 changed files with 45 additions and 218 deletions

View File

@ -56,6 +56,15 @@ var gClearSiteDataDialog = {
onClear() {
let allowed = true;
if (this._clearCacheCheckbox.checked && allowed) {
SiteDataManager.removeCache();
// If we're not clearing site data, we need to tell the
// SiteDataManager to signal that it's updating.
if (!this._clearSiteDataCheckbox.checked) {
SiteDataManager.updateSites();
}
}
if (this._clearSiteDataCheckbox.checked) {
allowed = SiteDataManager.promptSiteDataRemoval(window);
if (allowed) {
@ -63,12 +72,6 @@ var gClearSiteDataDialog = {
}
}
if (this._clearCacheCheckbox.checked && allowed) {
SiteDataManager.removeCache();
// Update cache UI in about:preferences
window.opener.gPrivacyPane.updateActualCacheSize();
}
if (allowed) {
window.close();
}

View File

@ -111,11 +111,6 @@ Preferences.addAll([
{ id: "browser.safebrowsing.downloads.remote.block_potentially_unwanted", type: "bool" },
{ id: "browser.safebrowsing.downloads.remote.block_uncommon", type: "bool" },
// Network tab
{ id: "browser.cache.disk.capacity", type: "int" },
{ id: "browser.cache.disk.smart_size.enabled", type: "bool", inverted: "true" },
]);
// Data Choices tab
@ -328,14 +323,10 @@ var gPrivacyPane = {
gPrivacyPane.showCertificates);
setEventListener("viewSecurityDevicesButton", "command",
gPrivacyPane.showSecurityDevices);
setEventListener("clearCacheButton", "command",
gPrivacyPane.clearCache);
this._pane = document.getElementById("panePrivacy");
this._initMasterPasswordUI();
this._initSafeBrowsing();
this.updateCacheSizeInputField();
this.updateActualCacheSize();
setEventListener("notificationSettingsButton", "command",
gPrivacyPane.showNotificationExceptions);
@ -370,9 +361,6 @@ var gPrivacyPane = {
}
}
setEventListener("cacheSize", "change",
gPrivacyPane.updateCacheSizePref);
if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
Services.obs.addObserver(this, "sitedatamanager:sites-updated");
Services.obs.addObserver(this, "sitedatamanager:updating-sites");
@ -1418,16 +1406,6 @@ var gPrivacyPane = {
gSubDialog.open("chrome://pippki/content/device_manager.xul");
},
/**
* Clears the cache.
*/
clearCache() {
try {
Services.cache2.clear();
} catch (ex) { }
this.updateActualCacheSize();
},
showSiteDataSettings() {
gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
},
@ -1439,90 +1417,20 @@ var gPrivacyPane = {
settingsButton.disabled = !shouldShow;
},
updateTotalDataSizeLabel(usage) {
let prefStrBundle = document.getElementById("bundlePreferences");
showSiteDataLoading() {
let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
if (usage < 0) {
totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize");
} else {
let size = DownloadUtils.convertByteUnits(usage);
totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
}
let prefStrBundle = document.getElementById("bundlePreferences");
totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize1");
},
// Retrieves the amount of space currently used by disk cache
updateActualCacheSize() {
var actualSizeLabel = document.getElementById("actualDiskCacheSize");
var prefStrBundle = document.getElementById("bundlePreferences");
// Needs to root the observer since cache service keeps only a weak reference.
this.observer = {
onNetworkCacheDiskConsumption(consumption) {
var size = DownloadUtils.convertByteUnits(consumption);
// The XBL binding for the string bundle may have been destroyed if
// the page was closed before this callback was executed.
if (!prefStrBundle.getFormattedString) {
return;
}
actualSizeLabel.textContent = prefStrBundle.getFormattedString("actualDiskCacheSize", size);
},
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsICacheStorageConsumptionObserver,
Components.interfaces.nsISupportsWeakReference
])
};
actualSizeLabel.textContent = prefStrBundle.getString("actualDiskCacheSizeCalculated");
try {
Services.cache2.asyncGetDiskConsumption(this.observer);
} catch (e) { }
},
updateCacheSizeUI(smartSizeEnabled) {
document.getElementById("useCacheBefore").disabled = smartSizeEnabled;
document.getElementById("cacheSize").disabled = smartSizeEnabled;
document.getElementById("useCacheAfter").disabled = smartSizeEnabled;
},
readSmartSizeEnabled() {
// The smart_size.enabled preference element is inverted="true", so its
// value is the opposite of the actual pref value
var disabled = Preferences.get("browser.cache.disk.smart_size.enabled").value;
this.updateCacheSizeUI(!disabled);
},
/**
* Converts the cache size from units of KB to units of MB and stores it in
* the textbox element.
*
* Preferences:
*
* browser.cache.disk.capacity
* - the size of the browser cache in KB
* - Only used if browser.cache.disk.smart_size.enabled is disabled
*/
updateCacheSizeInputField() {
let cacheSizeElem = document.getElementById("cacheSize");
let cachePref = Preferences.get("browser.cache.disk.capacity");
cacheSizeElem.value = cachePref.value / 1024;
if (cachePref.locked)
cacheSizeElem.disabled = true;
},
/**
* Updates the cache size preference once user enters a new value.
* We intentionally do not set preference="browser.cache.disk.capacity"
* onto the textbox directly, as that would update the pref at each keypress
* not only after the final value is entered.
*/
updateCacheSizePref() {
let cacheSizeElem = document.getElementById("cacheSize");
let cachePref = Preferences.get("browser.cache.disk.capacity");
// Converts the cache size as specified in UI (in MB) to KB.
let intValue = parseInt(cacheSizeElem.value, 10);
cachePref.value = isNaN(intValue) ? 0 : intValue * 1024;
updateTotalDataSizeLabel(siteDataUsage) {
SiteDataManager.getCacheSize().then(function(cacheUsage) {
let prefStrBundle = document.getElementById("bundlePreferences");
let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
let totalUsage = siteDataUsage + cacheUsage;
let size = DownloadUtils.convertByteUnits(totalUsage);
totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize1", size);
});
},
clearSiteData() {
@ -1593,7 +1501,7 @@ var gPrivacyPane = {
case "sitedatamanager:updating-sites":
// While updating, we want to disable this section and display loading message until updated
this.toggleSiteData(false);
this.updateTotalDataSizeLabel(-1);
this.showSiteDataLoading();
break;
case "sitedatamanager:sites-updated":

View File

@ -261,33 +261,6 @@
</label>
</groupbox>
<!-- Cache -->
<groupbox id="cacheGroup" data-category="panePrivacy" hidden="true">
<caption><label>&httpCache.label;</label></caption>
<hbox align="center">
<label id="actualDiskCacheSize" flex="1"/>
<button id="clearCacheButton"
class="accessory-button"
icon="clear"
label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"/>
</hbox>
<checkbox preference="browser.cache.disk.smart_size.enabled"
id="allowSmartSize"
onsyncfrompreference="return gPrivacyPane.readSmartSizeEnabled();"
label="&overrideSmartCacheSize.label;"
accesskey="&overrideSmartCacheSize.accesskey;"/>
<hbox align="center" class="indent">
<label id="useCacheBefore" control="cacheSize"
accesskey="&limitCacheSizeBefore.accesskey;">
&limitCacheSizeBefore.label;
</label>
<textbox id="cacheSize" type="number" size="4" max="1024"
aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
<label id="useCacheAfter" flex="1">&limitCacheSizeAfter.label;</label>
</hbox>
</groupbox>
<!-- Site Data -->
<groupbox id="siteDataGroup" hidden="true" data-category="panePrivacy" data-hidden-from-search="true">
<caption><label>&siteData.label;</label></caption>

View File

@ -16,10 +16,6 @@ function test() {
});
SpecialPowers.pushPrefEnv({set: [
["browser.cache.offline.enable", false],
["browser.cache.disk.enable", false],
["browser.cache.memory.enable", false],
["browser.storageManager.enabled", true],
["privacy.userContext.ui.enabled", true]
]}).then(() => open_preferences(runTest));
}

View File

@ -16,35 +16,6 @@ const TEST_OFFLINE_ORIGIN = "https://" + TEST_OFFLINE_HOST;
const TEST_OFFLINE_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/offline/offline.html";
const TEST_SERVICE_WORKER_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/service_worker_test.html";
// XXX: The intermittent bug 1331851
// The implementation of nsICacheStorageConsumptionObserver must be passed as weak referenced,
// so we must hold this observer here well. If we didn't, there would be a chance that
// in Linux debug test run the observer was released before the operation at gecko was completed
// (may be because of a relatively quicker GC cycle or a relatively slower operation).
// As a result of that, we would never get the cache usage we want so the test would fail from timeout.
const cacheUsageGetter = {
_promise: null,
_resolve: null,
get() {
if (!this._promise) {
this._promise = new Promise(resolve => {
this._resolve = resolve;
Services.cache2.asyncGetDiskConsumption(this);
});
}
return this._promise;
},
// nsICacheStorageConsumptionObserver implementations
onNetworkCacheDiskConsumption(usage) {
cacheUsageGetter._promise = null;
cacheUsageGetter._resolve(usage);
},
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsICacheStorageConsumptionObserver,
Components.interfaces.nsISupportsWeakReference
]),
};
async function testClearData(clearSiteData, clearCache) {
let quotaURI = Services.io.newURI(TEST_QUOTA_USAGE_ORIGIN);
SitePermissions.set(quotaURI, "persistent-storage", SitePermissions.ALLOW);
@ -69,13 +40,18 @@ async function testClearData(clearSiteData, clearCache) {
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
// Test the initial states.
let cacheUsage = await cacheUsageGetter.get();
let cacheUsage = await SiteDataManager.getCacheSize();
let quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
let totalUsage = await SiteDataManager.getTotalUsage();
Assert.greater(cacheUsage, 0, "The cache usage should not be 0");
Assert.greater(quotaUsage, 0, "The quota usage should not be 0");
Assert.greater(totalUsage, 0, "The total usage should not be 0");
let initialSizeLabelValue = await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
let sizeLabel = content.document.getElementById("totalSiteDataSize");
return sizeLabel.textContent;
});
let doc = gBrowser.selectedBrowser.contentDocument;
let clearSiteDataButton = doc.getElementById("clearSiteDataButton");
@ -145,11 +121,11 @@ async function testClearData(clearSiteData, clearCache) {
if (clearCache) {
TestUtils.waitForCondition(async function() {
let usage = await cacheUsageGetter.get();
let usage = await SiteDataManager.getCacheSize();
return usage == 0;
}, "The cache usage should be removed");
} else {
Assert.greater(await cacheUsageGetter.get(), 0, "The cache usage should not be 0");
Assert.greater(await SiteDataManager.getCacheSize(), 0, "The cache usage should not be 0");
}
if (clearSiteData) {
@ -161,14 +137,6 @@ async function testClearData(clearSiteData, clearCache) {
let usage = await SiteDataManager.getTotalUsage();
return usage == 0;
}, "The total usage should be removed");
// Check that the size label in about:preferences updates after we cleared data.
await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
let sizeLabel = content.document.getElementById("totalSiteDataSize");
await ContentTaskUtils.waitForCondition(
() => sizeLabel.textContent.includes("0"), "Site data size label should have updated.");
});
} else {
quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
totalUsage = await SiteDataManager.getTotalUsage();
@ -176,6 +144,15 @@ async function testClearData(clearSiteData, clearCache) {
Assert.greater(totalUsage, 0, "The total usage should not be 0");
}
if (clearCache || clearSiteData) {
// Check that the size label in about:preferences updates after we cleared data.
await ContentTask.spawn(gBrowser.selectedBrowser, {initialSizeLabelValue}, async function(opts) {
let sizeLabel = content.document.getElementById("totalSiteDataSize");
await ContentTaskUtils.waitForCondition(
() => sizeLabel.textContent != opts.initialSizeLabelValue, "Site data size label should have updated.");
});
}
let desiredPermissionState = clearSiteData ? SitePermissions.UNKNOWN : SitePermissions.ALLOW;
let permission = SitePermissions.get(quotaURI, "persistent-storage");
is(permission.state, desiredPermissionState, "Should have the correct permission state.");

View File

@ -71,6 +71,7 @@ add_task(async function() {
let updatedPromise = promiseSiteDataManagerSitesUpdated();
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
await updatedPromise;
let cacheSize = await SiteDataManager.getCacheSize();
let actual = null;
let expected = null;
@ -85,7 +86,7 @@ add_task(async function() {
.then(usage => {
actual = totalSiteDataSizeLabel.textContent;
expected = prefStrBundle.getFormattedString(
"totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
"totalSiteDataSize1", DownloadUtils.convertByteUnits(usage + cacheSize));
is(actual, expected, "Should show the right total site data size");
});
@ -93,17 +94,18 @@ add_task(async function() {
is(clearBtn.disabled, true, "Should disable clear button while updating sites");
is(settingsButton.disabled, true, "Should disable settings button while updating sites");
actual = totalSiteDataSizeLabel.textContent;
expected = prefStrBundle.getString("loadingSiteDataSize");
expected = prefStrBundle.getString("loadingSiteDataSize1");
is(actual, expected, "Should show the loading message while updating");
Services.obs.notifyObservers(null, "sitedatamanager:sites-updated");
is(clearBtn.disabled, false, "Should enable clear button after sites updated");
is(settingsButton.disabled, false, "Should enable settings button after sites updated");
cacheSize = await SiteDataManager.getCacheSize();
await SiteDataManager.getTotalUsage()
.then(usage => {
actual = totalSiteDataSizeLabel.textContent;
expected = prefStrBundle.getFormattedString(
"totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
"totalSiteDataSize1", DownloadUtils.convertByteUnits(usage + cacheSize));
is(actual, expected, "Should show the right total site data size");
});

View File

@ -53,8 +53,6 @@ available. -->
<!ENTITY connectionSettings.label "Settings…">
<!ENTITY connectionSettings.accesskey "e">
<!ENTITY httpCache.label "Cached Web Content">
<!-- Site Data section manages sites using Storage API and is under Network -->
<!ENTITY siteData.label "Site Data">
<!ENTITY clearSiteData.label "Clear All Data">
@ -63,20 +61,6 @@ available. -->
<!ENTITY siteDataSettings.accesskey "i">
<!ENTITY siteDataLearnMoreLink.label "Learn more">
<!-- LOCALIZATION NOTE:
The entities limitCacheSizeBefore.label and limitCacheSizeAfter.label appear on a single
line in preferences as follows:
&limitCacheSizeBefore.label [textbox for cache size in MB] &limitCacheSizeAfter.label;
-->
<!ENTITY limitCacheSizeBefore.label "Limit cache to">
<!ENTITY limitCacheSizeBefore.accesskey "L">
<!ENTITY limitCacheSizeAfter.label "MB of space">
<!ENTITY clearCacheNow.label "Clear Now">
<!ENTITY clearCacheNow.accesskey "C">
<!ENTITY overrideSmartCacheSize.label "Override automatic cache management">
<!ENTITY overrideSmartCacheSize.accesskey "O">
<!ENTITY updateTab.label "Update">
<!-- LOCALIZATION NOTE (updateApplication.label):

View File

@ -166,28 +166,12 @@ removeSelectedCookies.accesskey=R
defaultUserContextLabel=None
####Preferences::Advanced::Network
#LOCALIZATION NOTE: The next string is for the disk usage of the web content cache.
# e.g., "Your web content cache is currently using 200 MB"
# %1$S = size
# %2$S = unit (MB, KB, etc.)
actualDiskCacheSize=Your web content cache is currently using %1$S %2$S of disk space
actualDiskCacheSizeCalculated=Calculating web content cache size…
####Preferences::Advanced::Network
#LOCALIZATION NOTE: The next string is for the disk usage of the application cache.
# e.g., "Your application cache is currently using 200 MB"
# %1$S = size
# %2$S = unit (MB, KB, etc.)
actualAppCacheSize=Your application cache is currently using %1$S %2$S of disk space
####Preferences::Advanced::Network
#LOCALIZATION NOTE: The next string is for the total usage of site data.
# e.g., "The total usage is currently using 200 MB"
# %1$S = size
# %2$S = unit (MB, KB, etc.)
totalSiteDataSize=Your stored site data is currently using %1$S %2$S of disk space
loadingSiteDataSize=Calculating site data size…
totalSiteDataSize1=Your stored site data and cache are currently using %1$S %2$S of disk space
loadingSiteDataSize1=Calculating site data and cache size…
persistent=Persistent
siteUsage=%1$S %2$S
acceptRemove=Remove