Bug 1364936 - Allow WebExtensions to disable the browser cache, r?aswan
MozReview-Commit-ID: KhupGnBT5mZ
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -91,16 +91,17 @@ webextPerms.updateAccept.accessKey=U
webextPerms.optionalPermsHeader=%S requests additional permissions.
webextPerms.optionalPermsListIntro=It wants to:
webextPerms.optionalPermsAllow.label=Allow
webextPerms.optionalPermsAllow.accessKey=A
webextPerms.optionalPermsDeny.label=Deny
webextPerms.optionalPermsDeny.accessKey=D
webextPerms.description.bookmarks=Read and modify bookmarks
+webextPerms.description.browserSettings=Read and modify browser settings
webextPerms.description.clipboardRead=Get data from the clipboard
webextPerms.description.clipboardWrite=Input data to the clipboard
webextPerms.description.downloads=Download files and read and modify the browser’s download history
webextPerms.description.geolocation=Access your location
webextPerms.description.history=Access browsing history
webextPerms.description.management=Monitor extension usage and manage themes
# LOCALIZATION NOTE (webextPerms.description.nativeMessaging)
# %S will be replaced with the name of the application
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/ext-browserSettings.js
@@ -0,0 +1,61 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
+Cu.import("resource://gre/modules/ExtensionPreferencesManager.jsm");
+
+function getAPI(extension, name, callback) {
+ return {
+ async get(details) {
+ return {
+ levelOfControl: details.incognito ?
+ "not_controllable" :
+ await ExtensionPreferencesManager.getLevelOfControl(
+ extension, name),
+ value: await callback(),
+ };
+ },
+ set(details) {
+ return ExtensionPreferencesManager.setSetting(
+ extension, name, details.value);
+ },
+ clear(details) {
+ return ExtensionPreferencesManager.removeSetting(extension, name);
+ },
+ };
+}
+
+// Add settings objects for supported APIs to the preferences manager.
+ExtensionPreferencesManager.addSetting("cacheEnabled", {
+ prefNames: [
+ "browser.cache.disk.enable",
+ "browser.cache.memory.enable",
+ ],
+
+ setCallback(value) {
+ let returnObj = {};
+ for (let pref of this.prefNames) {
+ returnObj[pref] = value;
+ }
+ return returnObj;
+ },
+});
+
+this.browserSettings = class extends ExtensionAPI {
+ getAPI(context) {
+ let {extension} = context;
+ return {
+ browserSettings: {
+ cacheEnabled: getAPI(extension,
+ "cacheEnabled",
+ () => {
+ return Preferences.get("browser.cache.disk.enable") &&
+ Preferences.get("browser.cache.memory.enable");
+ }),
+ },
+ };
+ }
+};
--- a/toolkit/components/extensions/ext-toolkit.js
+++ b/toolkit/components/extensions/ext-toolkit.js
@@ -85,16 +85,24 @@ extensions.registerModules({
["alarms"],
],
},
backgroundPage: {
url: "chrome://extensions/content/ext-backgroundPage.js",
scopes: ["addon_parent"],
manifest: ["background"],
},
+ browserSettings: {
+ url: "chrome://extensions/content/ext-browserSettings.js",
+ schema: "chrome://extensions/content/schemas/browser_settings.json",
+ scopes: ["addon_parent"],
+ paths: [
+ ["browserSettings"],
+ ],
+ },
contextualIdentities: {
url: "chrome://extensions/content/ext-contextualIdentities.js",
schema: "chrome://extensions/content/schemas/contextual_identities.json",
scopes: ["addon_parent"],
paths: [
["contextualIdentities"],
],
},
--- a/toolkit/components/extensions/jar.mn
+++ b/toolkit/components/extensions/jar.mn
@@ -2,16 +2,17 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
% content extensions %content/extensions/
content/extensions/ext-alarms.js
content/extensions/ext-backgroundPage.js
content/extensions/ext-browser-content.js
+ content/extensions/ext-browserSettings.js
content/extensions/ext-contextualIdentities.js
content/extensions/ext-cookies.js
content/extensions/ext-downloads.js
content/extensions/ext-extension.js
content/extensions/ext-geolocation.js
content/extensions/ext-i18n.js
content/extensions/ext-idle.js
content/extensions/ext-management.js
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/schemas/browser_settings.json
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ {
+ "namespace": "manifest",
+ "types": [
+ {
+ "$extend": "Permission",
+ "choices": [{
+ "type": "string",
+ "enum": [
+ "browserSettings"
+ ]
+ }]
+ }
+ ]
+ },
+ {
+ "namespace": "browserSettings",
+ "description": "Use the <code>browser.browserSettings</code> API to control global settings of the browser.",
+ "permissions": ["browserSettings"],
+ "properties": {
+ "cacheEnabled": {
+ "$ref": "types.Setting",
+ "description": "Enables or disables the browser cache."
+ }
+ }
+ }
+]
--- a/toolkit/components/extensions/schemas/jar.mn
+++ b/toolkit/components/extensions/schemas/jar.mn
@@ -1,15 +1,16 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
% content extensions %content/extensions/
content/extensions/schemas/alarms.json
+ content/extensions/schemas/browser_settings.json
content/extensions/schemas/contextual_identities.json
content/extensions/schemas/cookies.json
content/extensions/schemas/downloads.json
content/extensions/schemas/events.json
content/extensions/schemas/experiments.json
content/extensions/schemas/extension.json
content/extensions/schemas/extension_types.json
content/extensions/schemas/extension_protocol_handlers.json
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_browserSettings.js
@@ -0,0 +1,86 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPreferencesManager",
+ "resource://gre/modules/ExtensionPreferencesManager.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
+const {
+ createAppInfo,
+ promiseShutdownManager,
+ promiseStartupManager,
+} = AddonTestUtils;
+
+AddonTestUtils.init(this);
+
+createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
+
+add_task(async function test_browser_settings() {
+ // Create an object to hold the values to which we will initialize the prefs.
+ const PREFS = {
+ "browser.cache.disk.enable": true,
+ "browser.cache.memory.enable": true,
+ };
+
+ async function background() {
+ browser.test.onMessage.addListener(async (msg, apiName, value) => {
+ let apiObj = browser.browserSettings[apiName];
+ await apiObj.set({value});
+ browser.test.sendMessage("settingData", await apiObj.get({}));
+ });
+ }
+
+ // Set prefs to our initial values.
+ for (let pref in PREFS) {
+ Preferences.set(pref, PREFS[pref]);
+ }
+
+ do_register_cleanup(() => {
+ // Reset the prefs.
+ for (let pref in PREFS) {
+ Preferences.reset(pref);
+ }
+ });
+
+ let extension = ExtensionTestUtils.loadExtension({
+ background,
+ manifest: {
+ permissions: ["browserSettings"],
+ },
+ useAddonManager: "temporary",
+ });
+
+ await promiseStartupManager();
+ await extension.startup();
+
+ async function testSetting(setting, value, expected) {
+ extension.sendMessage("set", setting, value);
+ let data = await extension.awaitMessage("settingData");
+ equal(data.value, value,
+ `The ${setting} setting has the expected value.`);
+ equal(data.levelOfControl, "controlled_by_this_extension",
+ `The ${setting} setting has the expected levelOfControl.`);
+ for (let pref in expected) {
+ equal(Preferences.get(pref), expected[pref], `${pref} set correctly for ${value}`);
+ }
+ }
+
+ await testSetting(
+ "cacheEnabled", false,
+ {
+ "browser.cache.disk.enable": false,
+ "browser.cache.memory.enable": false,
+ });
+ await testSetting(
+ "cacheEnabled", true,
+ {
+ "browser.cache.disk.enable": true,
+ "browser.cache.memory.enable": true,
+ });
+
+ await extension.unload();
+
+ await promiseShutdownManager();
+});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini
@@ -24,16 +24,17 @@ tags = webextensions
[test_ext_background_generated_reload.js]
[test_ext_background_global_history.js]
skip-if = os == "android" # Android does not use Places for history.
[test_ext_background_private_browsing.js]
[test_ext_background_runtime_connect_params.js]
[test_ext_background_sub_windows.js]
[test_ext_background_window_properties.js]
skip-if = os == "android"
+[test_ext_browserSettings.js]
[test_ext_contexts.js]
[test_ext_contextual_identities.js]
skip-if = os == "android" # Containers are not exposed to android.
[test_ext_debugging_utils.js]
[test_ext_downloads.js]
[test_ext_downloads_download.js]
skip-if = os == "android"
[test_ext_downloads_misc.js]