Bug 1362994 - Implement browsingData.settings WebExtension API method on android. r=bsilverberg,mattw,sebastian

MozReview-Commit-ID: G9frPBFPHCT

--HG--
rename : browser/components/extensions/schemas/browsing_data.json => mobile/android/components/extensions/schemas/browsing_data.json
extra : rebase_source : d6024c5e508a968ee9a22a991ef670afe4bc8d5a
This commit is contained in:
Tushar Saini (:shatur) 2017-06-02 23:11:49 +05:30
Родитель c5d48d3522
Коммит c7c7a878ef
7 изменённых файлов: 597 добавлений и 0 удалений

Просмотреть файл

@ -59,6 +59,15 @@ extensions.registerModules({
["browserAction"],
],
},
browsingData: {
url: "chrome://browser/content/ext-browsingData.js",
schema: "chrome://browser/content/schemas/browsing_data.json",
scopes: ["addon_parent"],
manifest: ["browsing_data"],
paths: [
["browsingData"],
],
},
pageAction: {
url: "chrome://browser/content/ext-pageAction.js",
schema: "chrome://browser/content/schemas/page_action.json",

Просмотреть файл

@ -0,0 +1,57 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
Cu.import("resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SharedPreferences",
"resource://gre/modules/SharedPreferences.jsm");
this.browsingData = class extends ExtensionAPI {
getAPI(context) {
return {
browsingData: {
settings() {
const PREF_DOMAIN = "android.not_a_preference.privacy.clear";
const PREF_KEY_PREFIX = "private.data.";
// The following prefs are the only ones in Firefox that match corresponding
// values used by Chrome when returning settings.
const PREF_LIST = ["cache", "history", "formdata", "cookies_sessions", "downloadFiles"];
let dataTrue = SharedPreferences.forProfile().getSetPref(PREF_DOMAIN);
let name;
let dataToRemove = {};
let dataRemovalPermitted = {};
for (let item of PREF_LIST) {
// The property formData needs a different case than the
// formdata preference.
switch(item){
case "formdata":
name = "formData";
break;
case "cookies_sessions":
name = "cookies";
break;
case "downloadFiles":
name = "downloads";
break;
default:
name = item;
}
dataToRemove[name] = dataTrue.includes(`${PREF_KEY_PREFIX}${item}`);
// Firefox doesn't have the same concept of dataRemovalPermitted
// as Chrome, so it will always be true.
dataRemovalPermitted[name] = true;
}
// We do not provide option to delete history by time
// so, since value is given 0, which means Everything
return Promise.resolve({options: {since: 0}, dataToRemove, dataRemovalPermitted});
},
},
};
}
};

Просмотреть файл

@ -7,6 +7,7 @@ chrome.jar:
content/ext-c-android.js
content/ext-c-tabs.js
content/ext-browserAction.js
content/ext-browsingData.js
content/ext-pageAction.js
content/ext-tabs.js
content/ext-utils.js

Просмотреть файл

@ -0,0 +1,427 @@
// 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": [
"browsingData"
]
}]
}
]
},
{
"namespace": "browsingData",
"description": "Use the <code>chrome.browsingData</code> API to remove browsing data from a user's local profile.",
"permissions": ["browsingData"],
"types": [
{
"id": "RemovalOptions",
"type": "object",
"description": "Options that determine exactly what data will be removed.",
"properties": {
"since": {
"$ref": "extensionTypes.Date",
"optional": true,
"description": "Remove data accumulated on or after this date, represented in milliseconds since the epoch (accessible via the <code>getTime</code> method of the JavaScript <code>Date</code> object). If absent, defaults to 0 (which would remove all browsing data)."
},
"hostnames": {
"type": "array",
"items": {"type": "string", "format": "hostname"},
"optional": true,
"description": "Only remove data associated with these hostnames (only applies to cookies)."
},
"originTypes": {
"type": "object",
"optional": true,
"description": "An object whose properties specify which origin types ought to be cleared. If this object isn't specified, it defaults to clearing only \"unprotected\" origins. Please ensure that you <em>really</em> want to remove application data before adding 'protectedWeb' or 'extensions'.",
"properties": {
"unprotectedWeb": {
"type": "boolean",
"optional": true,
"description": "Normal websites."
},
"protectedWeb": {
"type": "boolean",
"optional": true,
"description": "Websites that have been installed as hosted applications (be careful!)."
},
"extension": {
"type": "boolean",
"optional": true,
"description": "Extensions and packaged applications a user has installed (be _really_ careful!)."
}
}
}
}
},
{
"id": "DataTypeSet",
"type": "object",
"description": "A set of data types. Missing data types are interpreted as <code>false</code>.",
"properties": {
"cache": {
"type": "boolean",
"optional": true,
"description": "The browser's cache. Note: when removing data, this clears the <em>entire</em> cache: it is not limited to the range you specify."
},
"cookies": {
"type": "boolean",
"optional": true,
"description": "The browser's cookies."
},
"downloads": {
"type": "boolean",
"optional": true,
"description": "The browser's download list."
},
"formData": {
"type": "boolean",
"optional": true,
"description": "The browser's stored form data."
},
"history": {
"type": "boolean",
"optional": true,
"description": "The browser's history."
},
"indexedDB": {
"type": "boolean",
"optional": true,
"description": "Websites' IndexedDB data."
},
"localStorage": {
"type": "boolean",
"optional": true,
"description": "Websites' local storage data."
},
"serverBoundCertificates": {
"type": "boolean",
"optional": true,
"description": "Server-bound certificates."
},
"passwords": {
"type": "boolean",
"optional": true,
"description": "Stored passwords."
},
"pluginData": {
"type": "boolean",
"optional": true,
"description": "Plugins' data."
},
"serviceWorkers": {
"type": "boolean",
"optional": true,
"description": "Service Workers."
}
}
}
],
"functions": [
{
"name": "settings",
"description": "Reports which types of data are currently selected in the 'Clear browsing data' settings UI. Note: some of the data types included in this API are not available in the settings UI, and some UI settings control more than one data type listed here.",
"type": "function",
"async": "callback",
"parameters": [
{
"name": "callback",
"type": "function",
"parameters": [
{
"name": "result",
"type": "object",
"properties": {
"options": {
"$ref": "RemovalOptions"
},
"dataToRemove": {
"$ref": "DataTypeSet",
"description": "All of the types will be present in the result, with values of <code>true</code> if they are both selected to be removed and permitted to be removed, otherwise <code>false</code>."
},
"dataRemovalPermitted": {
"$ref": "DataTypeSet",
"description": "All of the types will be present in the result, with values of <code>true</code> if they are permitted to be removed (e.g., by enterprise policy) and <code>false</code> if not."
}
}
}
]
}
]
},
{
"name": "remove",
"description": "Clears various types of browsing data stored in a user's profile.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "dataToRemove",
"$ref": "DataTypeSet",
"description": "The set of data types to remove."
},
{
"name": "callback",
"type": "function",
"description": "Called when deletion has completed.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeAppcache",
"description": "Clears websites' appcache data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when websites' appcache data has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeCache",
"description": "Clears the browser's cache.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when the browser's cache has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeCookies",
"description": "Clears the browser's cookies and server-bound certificates modified within a particular timeframe.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when the browser's cookies and server-bound certificates have been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeDownloads",
"description": "Clears the browser's list of downloaded files (<em>not</em> the downloaded files themselves).",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when the browser's list of downloaded files has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeFileSystems",
"description": "Clears websites' file system data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when websites' file systems have been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeFormData",
"description": "Clears the browser's stored form data (autofill).",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when the browser's form data has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeHistory",
"description": "Clears the browser's history.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when the browser's history has cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeIndexedDB",
"description": "Clears websites' IndexedDB data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when websites' IndexedDB data has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeLocalStorage",
"description": "Clears websites' local storage data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when websites' local storage has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removePluginData",
"description": "Clears plugins' data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when plugins' data has been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removePasswords",
"description": "Clears the browser's stored passwords.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when the browser's passwords have been cleared.",
"optional": true,
"parameters": []
}
]
},
{
"name": "removeWebSQL",
"description": "Clears websites' WebSQL data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",
"name": "options"
},
{
"name": "callback",
"type": "function",
"description": "Called when websites' WebSQL databases have been cleared.",
"optional": true,
"parameters": []
}
]
}
]
}
]

Просмотреть файл

@ -4,5 +4,6 @@
chrome.jar:
content/schemas/browser_action.json
content/schemas/browsing_data.json
content/schemas/page_action.json
content/schemas/tabs.json

Просмотреть файл

@ -6,6 +6,7 @@ tags = webextensions
[test_ext_browserAction_getTitle_setTitle.html]
[test_ext_browserAction_onClicked.html]
[test_ext_browsingData_settings.html]
[test_ext_pageAction_show_hide.html]
[test_ext_pageAction_getPopup_setPopup.html]
skip-if = os == 'android' # bug 1373170

Просмотреть файл

@ -0,0 +1,101 @@
<!DOCTYPE HTML>
<html>
<head>
<title>BrowsingData Settings test</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" href="chrome://mochikit/contents/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
var {SharedPreferences} = Cu.import("resource://gre/modules/SharedPreferences.jsm", {});
const PREF_DOMAIN = "android.not_a_preference.privacy.clear";
const PREF_KEY_PREFIX = "private.data.";
const SETTINGS_LIST = ["cache", "cookies", "history", "formData", "downloads"];
function checkPrefs(key, actualValue, prefs, prefSuffix) {
let prefValue = prefs.includes(`${PREF_KEY_PREFIX}${prefSuffix}`);
is(actualValue, prefValue, `${key} property of dataToRemove matches the expected pref.`);
}
function testSettingsPreferences(dataToRemove){
let prefs = SharedPreferences.forProfile().getSetPref(PREF_DOMAIN);
for (let key of Object.keys(dataToRemove)) {
switch(key){
case "formData":
checkPrefs(key, dataToRemove[key], prefs, "formdata");
break;
case "cookies":
checkPrefs(key, dataToRemove[key], prefs, "cookies_sessions");
break;
case "downloads":
checkPrefs(key, dataToRemove[key], prefs, "downloadFiles");
break;
default:
checkPrefs(key, dataToRemove[key], prefs, key);
}
}
}
add_task(async function testSettings() {
function background() {
browser.test.onMessage.addListener(async (msg) => {
if (msg == "retrieve-settings") {
let settings = await browser.browsingData.settings();
browser.test.sendMessage("settings", settings);
}
});
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
"permissions": ["browsingData"],
},
});
await extension.startup();
extension.sendMessage("retrieve-settings");
let {options, dataToRemove, dataRemovalPermitted} = await extension.awaitMessage("settings");
// Verify that we get the keys we expect.
is(SETTINGS_LIST.length, Object.keys(dataToRemove).length, `dataToRemove contains expected no of keys`);
is(SETTINGS_LIST.length, Object.keys(dataRemovalPermitted).length, `dataRemovalPermitted contains expected no of keys`);
for (let key of SETTINGS_LIST) {
is(true, dataRemovalPermitted[key],
`${key} property of dataRemovalPermitted matches the expected value.`);
}
// Verify values of dataToRemove keys are as expected.
testSettingsPreferences(dataToRemove);
// Verify object options returned as expected.
// For now, We do not provide option to delete history by time, so,
// since value is given 0, which means Everything.
is(options.since, 0, `options contains expected value.`);
// Explicitly set some prefs to true
const NEW_PREFS = ["private.data.cache", "private.data.cookies_sessions"];
SharedPreferences.forProfile().setSetPref(PREF_DOMAIN, NEW_PREFS);
extension.sendMessage("retrieve-settings");
let settings = await extension.awaitMessage("settings");
testSettingsPreferences(settings.dataToRemove);
await extension.unload();
});
</script>
</body>
</html>