mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Backed out 11 changesets (bug 1252998) for faling browser-chrome on browser/base/content/test/sanitize/browser_sanitize-offlineData.js
Backed out changeset a9ec63c01c50 (bug 1252998) Backed out changeset a3e5299b882a (bug 1252998) Backed out changeset aa511b206e21 (bug 1252998) Backed out changeset 5875848a48ab (bug 1252998) Backed out changeset 7fd2523680d1 (bug 1252998) Backed out changeset a45e28e573a4 (bug 1252998) Backed out changeset 92e8cc81b417 (bug 1252998) Backed out changeset da38d133549e (bug 1252998) Backed out changeset 5be23a98b47c (bug 1252998) Backed out changeset 609093736110 (bug 1252998) Backed out changeset f4955cf6447f (bug 1252998) --HG-- rename : browser/base/content/test/sanitize/browser_purgehistory_clears_sh.js => browser/base/content/test/general/browser_purgehistory_clears_sh.js rename : browser/base/content/test/sanitize/browser_sanitize-passwordDisabledHosts.js => browser/base/content/test/general/browser_sanitize-passwordDisabledHosts.js rename : browser/base/content/test/sanitize/browser_sanitize-sitepermissions.js => browser/base/content/test/general/browser_sanitize-sitepermissions.js rename : browser/base/content/test/sanitize/browser_sanitize-timespans.js => browser/base/content/test/general/browser_sanitize-timespans.js rename : browser/base/content/test/sanitize/browser_sanitizeDialog.js => browser/base/content/test/general/browser_sanitizeDialog.js
This commit is contained in:
parent
cec041e5f4
commit
04e91897cf
@ -64,9 +64,6 @@ with Files("test/popups/**"):
|
||||
with Files("test/referrer/**"):
|
||||
BUG_COMPONENT = ("Core", "Document Navigation")
|
||||
|
||||
with Files("test/sanitize/**"):
|
||||
BUG_COMPONENT = ("Firefox", "General")
|
||||
|
||||
with Files("test/siteIdentity/**"):
|
||||
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
|
||||
|
||||
|
@ -17,14 +17,12 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
console: "resource://gre/modules/Console.jsm",
|
||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
|
||||
OfflineAppCacheHelper: "resource:///modules/offlineAppCache.jsm",
|
||||
});
|
||||
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "sas",
|
||||
"@mozilla.org/storage/activity-service;1",
|
||||
"nsIStorageActivityService");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
"nsIServiceWorkerManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "quotaManagerService",
|
||||
"@mozilla.org/dom/quota-manager-service;1",
|
||||
"nsIQuotaManagerService");
|
||||
@ -286,48 +284,37 @@ Sanitizer.prototype = {
|
||||
|
||||
offlineApps: {
|
||||
async clear(range) {
|
||||
// AppCache: this doesn't wait for the cleanup to be complete.
|
||||
// AppCache
|
||||
Components.utils.import("resource:///modules/offlineAppCache.jsm");
|
||||
// This doesn't wait for the cleanup to be complete.
|
||||
OfflineAppCacheHelper.clear();
|
||||
|
||||
if (range) {
|
||||
let principals = sas.getActiveOrigins(range[0], range[1])
|
||||
.QueryInterface(Components.interfaces.nsIArray);
|
||||
|
||||
let promises = [];
|
||||
|
||||
for (let i = 0; i < principals.length; ++i) {
|
||||
let principal = principals.queryElementAt(i, Components.interfaces.nsIPrincipal);
|
||||
|
||||
if (principal.URI.scheme != "http" &&
|
||||
principal.URI.scheme != "https" &&
|
||||
principal.URI.scheme != "file") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// LocalStorage
|
||||
Services.obs.notifyObservers(null, "browser:purge-domain-data", principal.URI.host);
|
||||
|
||||
// ServiceWorkers
|
||||
await ServiceWorkerCleanUp.removeFromPrincipal(principal);
|
||||
|
||||
// QuotaManager
|
||||
promises.push(new Promise(r => {
|
||||
let req = quotaManagerService.clearStoragesForPrincipal(principal, null, false);
|
||||
req.callback = () => { r(); };
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
// LocalStorage
|
||||
Services.obs.notifyObservers(null, "extension:purge-localStorage");
|
||||
|
||||
// ServiceWorkers
|
||||
await ServiceWorkerCleanUp.removeAll();
|
||||
let promises = [];
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
|
||||
promises.push(new Promise(resolve => {
|
||||
let unregisterCallback = {
|
||||
unregisterSucceeded: () => { resolve(true); },
|
||||
// We don't care about failures.
|
||||
unregisterFailed: () => { resolve(true); },
|
||||
QueryInterface: XPCOMUtils.generateQI(
|
||||
[Ci.nsIServiceWorkerUnregisterCallback])
|
||||
};
|
||||
|
||||
serviceWorkerManager.propagateUnregister(sw.principal, unregisterCallback, sw.scope);
|
||||
}));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
// QuotaManager
|
||||
let promises = [];
|
||||
promises = [];
|
||||
await new Promise(resolve => {
|
||||
quotaManagerService.getUsage(request => {
|
||||
if (request.resultCode != Cr.NS_OK) {
|
||||
|
@ -387,6 +387,8 @@ skip-if = os == 'win' # Bug 1384127
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_private_no_prompt.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_purgehistory_clears_sh.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_PageMetaData_pushstate.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_refreshBlocker.js]
|
||||
@ -408,6 +410,14 @@ support-files =
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_restore_isAppTab.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_sanitize-passwordDisabledHosts.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_sanitize-sitepermissions.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_sanitize-timespans.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_sanitizeDialog.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_save_link-perwindowpb.js]
|
||||
skip-if = e10s && debug && os == "win" # Bug 1280505
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const url = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.org") + "dummy_page.html";
|
||||
const url = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
|
||||
|
||||
add_task(async function purgeHistoryTest() {
|
||||
await BrowserTestUtils.withNewTab({
|
@ -852,7 +852,7 @@ WindowHelper.prototype = {
|
||||
};
|
||||
|
||||
function promiseSanitizationComplete() {
|
||||
return TestUtils.topicObserved("sanitizer-sanitization-complete");
|
||||
return promiseTopicObserved("sanitizer-sanitization-complete");
|
||||
}
|
||||
|
||||
/**
|
@ -273,6 +273,24 @@ function waitForAsyncUpdates(aCallback, aScope, aArguments) {
|
||||
commit.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously check a url is visited.
|
||||
|
||||
* @param aURI The URI.
|
||||
* @param aExpectedValue The expected value.
|
||||
* @return {Promise}
|
||||
* @resolves When the check has been added successfully.
|
||||
* @rejects JavaScript exception.
|
||||
*/
|
||||
function promiseIsURIVisited(aURI, aExpectedValue) {
|
||||
return new Promise(resolve => {
|
||||
PlacesUtils.asyncHistory.isURIVisited(aURI, function(unused, aIsVisited) {
|
||||
resolve(aIsVisited);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function whenNewTabLoaded(aWindow, aCallback) {
|
||||
aWindow.BrowserOpenTab();
|
||||
|
||||
@ -296,6 +314,33 @@ function promiseTabLoaded(aTab) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the specified URIs are either cleared or not.
|
||||
*
|
||||
* @param aURIs
|
||||
* Array of page URIs
|
||||
* @param aShouldBeCleared
|
||||
* True if each visit to the URI should be cleared, false otherwise
|
||||
*/
|
||||
function promiseHistoryClearedState(aURIs, aShouldBeCleared) {
|
||||
return new Promise(resolve => {
|
||||
let callbackCount = 0;
|
||||
let niceStr = aShouldBeCleared ? "no longer" : "still";
|
||||
function callbackDone() {
|
||||
if (++callbackCount == aURIs.length)
|
||||
resolve();
|
||||
}
|
||||
aURIs.forEach(function(aURI) {
|
||||
PlacesUtils.asyncHistory.isURIVisited(aURI, function(uri, isVisited) {
|
||||
is(isVisited, !aShouldBeCleared,
|
||||
"history visit " + uri.spec + " should " + niceStr + " exist");
|
||||
callbackDone();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
var FullZoomHelper = {
|
||||
|
||||
selectTabAndWaitForLocationChange: function selectTabAndWaitForLocationChange(tab) {
|
||||
|
@ -1,8 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/browser-test",
|
||||
"plugin:mozilla/mochitest-test",
|
||||
]
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
dummy_page.html
|
||||
dummy.js
|
||||
head.js
|
||||
sanitize.html
|
||||
|
||||
[browser_purgehistory_clears_sh.js]
|
||||
[browser_sanitize-offlineData.js]
|
||||
[browser_sanitize-passwordDisabledHosts.js]
|
||||
[browser_sanitize-sitepermissions.js]
|
||||
[browser_sanitize-timespans.js]
|
||||
[browser_sanitizeDialog.js]
|
@ -1,192 +0,0 @@
|
||||
// Bug 380852 - Delete permission manager entries in Clear Recent History
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
let tempScope = {};
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/sanitize.js", tempScope);
|
||||
let Sanitizer = tempScope.Sanitizer;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "sas",
|
||||
"@mozilla.org/storage/activity-service;1",
|
||||
"nsIStorageActivityService");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "swm",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
"nsIServiceWorkerManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "quotaManagerService",
|
||||
"@mozilla.org/dom/quota-manager-service;1",
|
||||
"nsIQuotaManagerService");
|
||||
|
||||
const oneHour = 3600000000;
|
||||
const fiveHours = oneHour * 5;
|
||||
const itemsToClear = [ "cookies", "offlineApps" ];
|
||||
|
||||
function waitForUnregister(host) {
|
||||
return new Promise(resolve => {
|
||||
let listener = {
|
||||
onUnregister: registration => {
|
||||
if (registration.principal.URI.host != host) {
|
||||
return;
|
||||
}
|
||||
let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
|
||||
.getService(Ci.nsIServiceWorkerManager);
|
||||
swm.removeListener(listener);
|
||||
resolve(registration);
|
||||
}
|
||||
};
|
||||
swm.addListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
async function createData(host) {
|
||||
let pageURL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://" + host) + "sanitize.html";
|
||||
|
||||
return BrowserTestUtils.withNewTab(pageURL, async function(browser) {
|
||||
await ContentTask.spawn(browser, null, () => {
|
||||
return new content.window.Promise(resolve => {
|
||||
let id = content.window.setInterval(() => {
|
||||
if ("foobar" in content.window.localStorage) {
|
||||
content.window.clearInterval(id);
|
||||
resolve(true);
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function moveOriginInTime(principals, endDate, host) {
|
||||
for (let i = 0; i < principals.length; ++i) {
|
||||
let principal = principals.queryElementAt(i, Components.interfaces.nsIPrincipal);
|
||||
if (principal.URI.host == host) {
|
||||
sas.moveOriginInTime(principal, endDate - fiveHours);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function getData(host) {
|
||||
let dummyURL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://" + host) + "dummy_page.html";
|
||||
|
||||
// LocalStorage + IndexedDB
|
||||
let data = await BrowserTestUtils.withNewTab(dummyURL, async function(browser) {
|
||||
return ContentTask.spawn(browser, null, () => {
|
||||
return new content.window.Promise(resolve => {
|
||||
let obj = {
|
||||
localStorage: "foobar" in content.window.localStorage,
|
||||
indexedDB: true,
|
||||
serviceWorker: false,
|
||||
};
|
||||
|
||||
let request = content.window.indexedDB.open("sanitizer_test", 1);
|
||||
request.onupgradeneeded = event => {
|
||||
obj.indexedDB = false;
|
||||
};
|
||||
request.onsuccess = event => {
|
||||
resolve(obj);
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ServiceWorkers
|
||||
let serviceWorkers = swm.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
if (sw.principal.URI.host == host) {
|
||||
data.serviceWorker = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
add_task(async function testWithRange() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.testing.enabled", true]
|
||||
]});
|
||||
|
||||
// The service may have picked up activity from prior tests in this run.
|
||||
// Clear it.
|
||||
sas.testOnlyReset();
|
||||
|
||||
let endDate = Date.now() * 1000;
|
||||
let principals = sas.getActiveOrigins(endDate - oneHour, endDate);
|
||||
is(principals.length, 0, "starting from clear activity state");
|
||||
|
||||
let s = new Sanitizer();
|
||||
s.ignoreTimespan = false;
|
||||
s.prefDomain = "privacy.cpd.";
|
||||
|
||||
info("sanitize: " + itemsToClear.join(", "));
|
||||
await s.sanitize(itemsToClear);
|
||||
|
||||
await createData("example.org");
|
||||
await createData("example.com");
|
||||
|
||||
endDate = Date.now() * 1000;
|
||||
principals = sas.getActiveOrigins(endDate - oneHour, endDate);
|
||||
ok(!!principals, "We have an active origin.");
|
||||
ok(principals.length >= 2, "We have an active origin.");
|
||||
|
||||
let found = 0;
|
||||
for (let i = 0; i < principals.length; ++i) {
|
||||
let principal = principals.queryElementAt(i, Components.interfaces.nsIPrincipal);
|
||||
if (principal.URI.host == "example.org" ||
|
||||
principal.URI.host == "example.com") {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
is(found, 2, "Our origins are active.");
|
||||
|
||||
let dataPre = await getData("example.org");
|
||||
ok(dataPre.localStorage, "We have localStorage data");
|
||||
ok(dataPre.indexedDB, "We have indexedDB data");
|
||||
ok(dataPre.serviceWorker, "We have serviceWorker data");
|
||||
|
||||
dataPre = await getData("example.com");
|
||||
ok(dataPre.localStorage, "We have localStorage data");
|
||||
ok(dataPre.indexedDB, "We have indexedDB data");
|
||||
ok(dataPre.serviceWorker, "We have serviceWorker data");
|
||||
|
||||
// Let's move example.com in the past.
|
||||
ok(moveOriginInTime(principals, endDate, "example.com"), "Operation completed!");
|
||||
|
||||
let p = waitForUnregister("example.org");
|
||||
|
||||
// Clear it
|
||||
info("sanitize: " + itemsToClear.join(", "));
|
||||
await s.sanitize(itemsToClear);
|
||||
await p;
|
||||
|
||||
let dataPost = await getData("example.org");
|
||||
ok(!dataPost.localStorage, "We don't have localStorage data");
|
||||
ok(!dataPost.indexedDB, "We don't have indexedDB data");
|
||||
ok(!dataPost.serviceWorker, "We don't have serviceWorker data");
|
||||
|
||||
dataPost = await getData("example.com");
|
||||
ok(dataPost.localStorage, "We still have localStorage data");
|
||||
ok(dataPost.indexedDB, "We still have indexedDB data");
|
||||
ok(dataPost.serviceWorker, "We still have serviceWorker data");
|
||||
|
||||
// We have to move example.com in the past because how we check IDB triggers
|
||||
// a storage activity.
|
||||
ok(moveOriginInTime(principals, endDate, "example.com"), "Operation completed!");
|
||||
|
||||
// Let's call the clean up again.
|
||||
info("sanitize again to ensure clearing doesn't expand the activity scope");
|
||||
await s.sanitize(itemsToClear);
|
||||
|
||||
dataPost = await getData("example.com");
|
||||
ok(dataPost.localStorage, "We still have localStorage data");
|
||||
ok(dataPost.indexedDB, "We still have indexedDB data");
|
||||
ok(dataPost.serviceWorker, "We still have serviceWorker data");
|
||||
|
||||
sas.testOnlyReset();
|
||||
});
|
@ -1,9 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Dummy test page</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
|
||||
</head>
|
||||
<body>
|
||||
<p>Dummy test page</p>
|
||||
</body>
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
/**
|
||||
* Asynchronously check a url is visited.
|
||||
|
||||
* @param aURI The URI.
|
||||
* @param aExpectedValue The expected value.
|
||||
* @return {Promise}
|
||||
* @resolves When the check has been added successfully.
|
||||
* @rejects JavaScript exception.
|
||||
*/
|
||||
function promiseIsURIVisited(aURI, aExpectedValue) {
|
||||
return new Promise(resolve => {
|
||||
PlacesUtils.asyncHistory.isURIVisited(aURI, function(unused, aIsVisited) {
|
||||
resolve(aIsVisited);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the specified URIs are either cleared or not.
|
||||
*
|
||||
* @param aURIs
|
||||
* Array of page URIs
|
||||
* @param aShouldBeCleared
|
||||
* True if each visit to the URI should be cleared, false otherwise
|
||||
*/
|
||||
function promiseHistoryClearedState(aURIs, aShouldBeCleared) {
|
||||
return new Promise(resolve => {
|
||||
let callbackCount = 0;
|
||||
let niceStr = aShouldBeCleared ? "no longer" : "still";
|
||||
function callbackDone() {
|
||||
if (++callbackCount == aURIs.length)
|
||||
resolve();
|
||||
}
|
||||
aURIs.forEach(function(aURI) {
|
||||
PlacesUtils.asyncHistory.isURIVisited(aURI, function(uri, isVisited) {
|
||||
is(isVisited, !aShouldBeCleared,
|
||||
"history visit " + uri.spec + " should " + niceStr + " exist");
|
||||
callbackDone();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
// indexedDB
|
||||
let p = new Promise(resolve => {
|
||||
let request = indexedDB.open("sanitizer_test", 1);
|
||||
request.onupgradeneeded = event => {
|
||||
let db = event.target.result;
|
||||
event.target.onsuccess = resolve;
|
||||
db.createObjectStore("foo", { autoIncrement: true });
|
||||
db.createObjectStore("bar", { autoIncrement: true });
|
||||
};
|
||||
});
|
||||
|
||||
// ServiceWorker
|
||||
p.then(() => {
|
||||
return navigator.serviceWorker.register("dummy.js")
|
||||
.then(r => {
|
||||
return new Promise(resolve => {
|
||||
let worker = r.installing;
|
||||
worker.addEventListener("statechange", () => {
|
||||
if (worker.state === "installed") {
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
// localStorage
|
||||
.then(() => {
|
||||
localStorage.foobar = "hello world!";
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -36,7 +36,6 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
'content/test/popupNotifications/browser.ini',
|
||||
'content/test/popups/browser.ini',
|
||||
'content/test/referrer/browser.ini',
|
||||
'content/test/sanitize/browser.ini',
|
||||
'content/test/sidebar/browser.ini',
|
||||
'content/test/siteIdentity/browser.ini',
|
||||
'content/test/static/browser.ini',
|
||||
|
@ -919,7 +919,7 @@ if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
|
||||
BrowserUITelemetry.countPanicEvent(group.selectedItem.id);
|
||||
group.selectedItem = doc.getElementById("PanelUI-panic-5min");
|
||||
let itemsToClear = [
|
||||
"cookies", "history", "openWindows", "formdata", "sessions", "cache", "downloads", "offlineApps"
|
||||
"cookies", "history", "openWindows", "formdata", "sessions", "cache", "downloads"
|
||||
];
|
||||
let newWindowPrivateState = PrivateBrowsingUtils.isWindowPrivate(doc.defaultView) ?
|
||||
"private" : "non-private";
|
||||
|
@ -13,8 +13,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
|
||||
"resource://gre/modules/Timer.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ServiceWorkerCleanUp",
|
||||
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
@ -155,6 +153,22 @@ const clearPluginData = options => {
|
||||
return sanitizer.items.pluginData.clear(makeRange(options));
|
||||
};
|
||||
|
||||
const clearServiceWorkers = async function() {
|
||||
// Clearing service workers does not support timestamps.
|
||||
let yieldCounter = 0;
|
||||
|
||||
// Iterate through the service workers and remove them.
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
let host = sw.principal.URI.host;
|
||||
serviceWorkerManager.removeAndPropagate(host);
|
||||
if (++yieldCounter % YIELD_PERIOD == 0) {
|
||||
await new Promise(resolve => setTimeout(resolve, 0)); // Don't block the main thread too long.
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const doRemoval = (options, dataToRemove, extension) => {
|
||||
if (options.originTypes &&
|
||||
(options.originTypes.protectedWeb || options.originTypes.extension)) {
|
||||
@ -195,7 +209,7 @@ const doRemoval = (options, dataToRemove, extension) => {
|
||||
removalPromises.push(clearPluginData(options));
|
||||
break;
|
||||
case "serviceWorkers":
|
||||
removalPromises.push(ServiceWorkerCleanUp.removeAll());
|
||||
removalPromises.push(clearServiceWorkers());
|
||||
break;
|
||||
default:
|
||||
invalidDataTypes.push(dataType);
|
||||
|
@ -9,8 +9,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "OfflineAppCacheHelper",
|
||||
"resource:///modules/offlineAppCache.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
|
||||
"resource://gre/modules/ContextualIdentityService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ServiceWorkerCleanUp",
|
||||
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
"nsIServiceWorkerManager");
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"SiteDataManager"
|
||||
@ -223,11 +224,28 @@ this.SiteDataManager = {
|
||||
}
|
||||
},
|
||||
|
||||
_unregisterServiceWorker(serviceWorker) {
|
||||
return new Promise(resolve => {
|
||||
let unregisterCallback = {
|
||||
unregisterSucceeded: resolve,
|
||||
unregisterFailed: resolve, // We don't care about failures.
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIServiceWorkerUnregisterCallback])
|
||||
};
|
||||
serviceWorkerManager.propagateUnregister(serviceWorker.principal, unregisterCallback, serviceWorker.scope);
|
||||
});
|
||||
},
|
||||
|
||||
_removeServiceWorkersForSites(sites) {
|
||||
let promises = [];
|
||||
sites.forEach(s => {
|
||||
promises.push(ServiceWorkerCleanUp.removeFromHost(s.principals[0].URI.host));
|
||||
});
|
||||
let targetHosts = sites.map(s => s.principals[0].URI.host);
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
// Sites are grouped and removed by host so we unregister service workers by the same host as well
|
||||
if (targetHosts.includes(sw.principal.URI.host)) {
|
||||
promises.push(this._unregisterServiceWorker(sw));
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
@ -265,7 +283,14 @@ this.SiteDataManager = {
|
||||
Services.cookies.removeAll();
|
||||
OfflineAppCacheHelper.clear();
|
||||
|
||||
await ServiceWorkerCleanUp.removeAll();
|
||||
// Iterate through the service workers and remove them.
|
||||
let promises = [];
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
promises.push(this._unregisterServiceWorker(sw));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
|
||||
// Refresh sites using quota usage again.
|
||||
// This is for the case:
|
||||
@ -278,7 +303,7 @@ this.SiteDataManager = {
|
||||
// because that would clear browser data as well too,
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1312361#c9
|
||||
await this._getQuotaUsage();
|
||||
let promises = [];
|
||||
promises = [];
|
||||
for (let site of this._sites.values()) {
|
||||
this._removePermission(site);
|
||||
promises.push(this._removeQuotaUsage(site));
|
||||
|
@ -187,6 +187,17 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
*/
|
||||
[noscript] nsISupports GetDocumentController(in nsPIDOMWindowInner aWindow);
|
||||
|
||||
/*
|
||||
* Clears ServiceWorker registrations from memory and disk for the specified
|
||||
* host.
|
||||
* - All ServiceWorker instances change their state to redundant.
|
||||
* - Existing ServiceWorker instances handling fetches will keep running.
|
||||
* - All documents will immediately stop being controlled.
|
||||
* - Unregister jobs will be queued for all registrations.
|
||||
* This eventually results in the registration being deleted from disk too.
|
||||
*/
|
||||
void removeAndPropagate(in AUTF8String aHost);
|
||||
|
||||
// Testing
|
||||
DOMString getScopeForUrl(in nsIPrincipal aPrincipal, in DOMString aPath);
|
||||
|
||||
|
@ -10,7 +10,6 @@ with Files("**"):
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMStorage.idl',
|
||||
'nsIDOMStorageManager.idl',
|
||||
'nsIStorageActivityService.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_storage'
|
||||
|
@ -1,42 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIArray;
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* nsIStorageActivityService is a service that can be used to know which
|
||||
* origins have been active in a time range. This information can be used to
|
||||
* implement "Clear Recent History" or similar features.
|
||||
*
|
||||
* If you are implementing a new Storage component, you should use
|
||||
* QuotaManager. But if you don't do it, remember to call
|
||||
* StorageActivityService methods in order to inform this service about
|
||||
* 'writing' operations executed by origins.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(fd1310ba-d1be-4327-988e-92b39fcff6f4)]
|
||||
interface nsIStorageActivityService : nsISupports
|
||||
{
|
||||
// This returns an array of nsIPrincipals, active between |from| and |to|
|
||||
// timestamps. Note activities older than 1 day are forgotten.
|
||||
// Activity details are not persisted, so this only covers activity since
|
||||
// Firefox was started. All codebase principals are logged, which includes
|
||||
// non-system principals like "moz-extension://ID", "moz-safe-about:home",
|
||||
// "about:newtab", so principals may need to be filtered before being used.
|
||||
nsIArray getActiveOrigins(in PRTime from, in PRTime to);
|
||||
|
||||
// NOTE: This method is meant to be used for testing only.
|
||||
// The activity of |origin| is moved to the specified timestamp |when|.
|
||||
void moveOriginInTime(in nsIPrincipal origin, in PRTime when);
|
||||
|
||||
// TEST-ONLY method to support clearing all previously known activity.
|
||||
void testOnlyReset();
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define STORAGE_ACTIVITY_SERVICE_CONTRACTID "@mozilla.org/storage/activity-service;1"
|
||||
%}
|
@ -36,7 +36,6 @@
|
||||
#include "mozilla/dom/quota/PQuotaParent.h"
|
||||
#include "mozilla/dom/quota/PQuotaRequestParent.h"
|
||||
#include "mozilla/dom/quota/PQuotaUsageRequestParent.h"
|
||||
#include "mozilla/dom/StorageActivityService.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
@ -3022,11 +3021,6 @@ QuotaObject::LockedMaybeUpdateSize(int64_t aSize, bool aTruncate)
|
||||
|
||||
quotaManager->mQuotaMutex.AssertCurrentThreadOwns();
|
||||
|
||||
if (mWritingDone == false && mOriginInfo) {
|
||||
mWritingDone = true;
|
||||
StorageActivityService::SendActivity(mOriginInfo->mOrigin);
|
||||
}
|
||||
|
||||
if (mQuotaCheckDisabled) {
|
||||
return true;
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ private:
|
||||
, mPath(aPath)
|
||||
, mSize(aSize)
|
||||
, mQuotaCheckDisabled(false)
|
||||
, mWritingDone(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(QuotaObject);
|
||||
}
|
||||
@ -87,7 +86,6 @@ private:
|
||||
int64_t mSize;
|
||||
|
||||
bool mQuotaCheckDisabled;
|
||||
bool mWritingDone;
|
||||
};
|
||||
|
||||
END_QUOTA_NAMESPACE
|
||||
|
@ -1,318 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "StorageActivityService.h"
|
||||
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsSupportsPrimitives.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
// This const is used to know when origin activities should be purged because
|
||||
// too old. This value should be in sync with what the UI needs.
|
||||
#define TIME_MAX_SECS 86400 /* 24 hours */
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static StaticRefPtr<StorageActivityService> gStorageActivityService;
|
||||
static bool gStorageActivityShutdown = false;
|
||||
|
||||
/* static */ void
|
||||
StorageActivityService::SendActivity(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!aPrincipal ||
|
||||
BasePrincipal::Cast(aPrincipal)->Kind() != BasePrincipal::eCodebasePrincipal) {
|
||||
// Only codebase principals.
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<StorageActivityService> service = GetOrCreate();
|
||||
if (NS_WARN_IF(!service)) {
|
||||
return;
|
||||
}
|
||||
|
||||
service->SendActivityInternal(aPrincipal);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
StorageActivityService::SendActivity(const mozilla::ipc::PrincipalInfo& aPrincipalInfo)
|
||||
{
|
||||
if (aPrincipalInfo.type() !=
|
||||
mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
|
||||
// only content principal.
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Runnable> r = NS_NewRunnableFunction(
|
||||
"StorageActivityService::SendActivity",
|
||||
[aPrincipalInfo] () {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
mozilla::ipc::PrincipalInfoToPrincipal(aPrincipalInfo);
|
||||
|
||||
StorageActivityService::SendActivity(principal);
|
||||
});
|
||||
|
||||
SystemGroup::Dispatch(TaskCategory::Other, r.forget());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
StorageActivityService::SendActivity(const nsACString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsCString origin;
|
||||
origin.Assign(aOrigin);
|
||||
|
||||
RefPtr<Runnable> r = NS_NewRunnableFunction(
|
||||
"StorageActivityService::SendActivity",
|
||||
[origin] () {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<StorageActivityService> service = GetOrCreate();
|
||||
if (NS_WARN_IF(!service)) {
|
||||
return;
|
||||
}
|
||||
|
||||
service->SendActivityInternal(origin);
|
||||
});
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
Unused << r->Run();
|
||||
} else {
|
||||
SystemGroup::Dispatch(TaskCategory::Other, r.forget());
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<StorageActivityService>
|
||||
StorageActivityService::GetOrCreate()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!gStorageActivityService && !gStorageActivityShutdown) {
|
||||
RefPtr<StorageActivityService> service = new StorageActivityService();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult rv = obs->AddObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gStorageActivityService = service;
|
||||
}
|
||||
|
||||
RefPtr<StorageActivityService> service = gStorageActivityService;
|
||||
return service.forget();
|
||||
}
|
||||
|
||||
StorageActivityService::StorageActivityService()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
StorageActivityService::~StorageActivityService()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mTimer);
|
||||
}
|
||||
|
||||
void
|
||||
StorageActivityService::SendActivityInternal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(BasePrincipal::Cast(aPrincipal)->Kind() == BasePrincipal::eCodebasePrincipal);
|
||||
|
||||
if (!XRE_IsParentProcess()) {
|
||||
SendActivityToParent(aPrincipal);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString origin;
|
||||
nsresult rv = aPrincipal->GetOrigin(origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendActivityInternal(origin);
|
||||
}
|
||||
|
||||
void
|
||||
StorageActivityService::SendActivityInternal(const nsACString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
mActivities.Put(aOrigin, PR_Now());
|
||||
MaybeStartTimer();
|
||||
}
|
||||
|
||||
void
|
||||
StorageActivityService::SendActivityToParent(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||
|
||||
PBackgroundChild* actor = BackgroundChild::GetOrCreateForCurrentThread();
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::ipc::PrincipalInfo principalInfo;
|
||||
nsresult rv =
|
||||
mozilla::ipc::PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
actor->SendStorageActivity(principalInfo);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StorageActivityService::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID));
|
||||
|
||||
MaybeStopTimer();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
}
|
||||
|
||||
gStorageActivityShutdown = true;
|
||||
gStorageActivityService = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
StorageActivityService::MaybeStartTimer()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mTimer) {
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
mTimer->InitWithCallback(this,
|
||||
1000 * 5 * 60 /* any 5 minutes */,
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StorageActivityService::MaybeStopTimer()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StorageActivityService::Notify(nsITimer* aTimer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mTimer == aTimer);
|
||||
|
||||
uint64_t now = PR_Now();
|
||||
|
||||
for (auto iter = mActivities.Iter(); !iter.Done(); iter.Next()) {
|
||||
if ((now - iter.UserData()) / PR_USEC_PER_SEC > TIME_MAX_SECS) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
// If no activities, let's stop the timer.
|
||||
if (mActivities.Count() == 0) {
|
||||
MaybeStopTimer();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StorageActivityService::GetActiveOrigins(PRTime aFrom, PRTime aTo,
|
||||
nsIArray** aRetval)
|
||||
{
|
||||
uint64_t now = PR_Now();
|
||||
if (((now - aFrom) / PR_USEC_PER_SEC) > TIME_MAX_SECS ||
|
||||
aFrom >= aTo) {
|
||||
return NS_ERROR_RANGE_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMutableArray> devices =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (auto iter = mActivities.Iter(); !iter.Done(); iter.Next()) {
|
||||
if (iter.UserData() >= aFrom && iter.UserData() <= aTo) {
|
||||
RefPtr<BasePrincipal> principal =
|
||||
BasePrincipal::CreateCodebasePrincipal(iter.Key());
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
rv = devices->AppendElement(principal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devices.forget(aRetval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StorageActivityService::MoveOriginInTime(nsIPrincipal* aPrincipal,
|
||||
PRTime aWhen)
|
||||
{
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoCString origin;
|
||||
nsresult rv = aPrincipal->GetOrigin(origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mActivities.Put(origin, aWhen / PR_USEC_PER_SEC);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StorageActivityService::TestOnlyReset()
|
||||
{
|
||||
mActivities.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(StorageActivityService)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStorageActivityService)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStorageActivityService)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(StorageActivityService)
|
||||
NS_IMPL_RELEASE(StorageActivityService)
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
@ -1,78 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_StorageActivityService_h
|
||||
#define mozilla_dom_StorageActivityService_h
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsIStorageActivityService.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
} // ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
class StorageActivityService final : public nsIStorageActivityService
|
||||
, public nsIObserver
|
||||
, public nsITimerCallback
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTORAGEACTIVITYSERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// Main-thread only.
|
||||
static void
|
||||
SendActivity(nsIPrincipal* aPrincipal);
|
||||
|
||||
// Thread-safe.
|
||||
static void
|
||||
SendActivity(const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
|
||||
|
||||
// Thread-safe but for parent process only!
|
||||
static void
|
||||
SendActivity(const nsACString& aOrigin);
|
||||
|
||||
// Used by XPCOM. Don't use it, use SendActivity() instead.
|
||||
static already_AddRefed<StorageActivityService>
|
||||
GetOrCreate();
|
||||
|
||||
private:
|
||||
StorageActivityService();
|
||||
~StorageActivityService();
|
||||
|
||||
void
|
||||
SendActivityInternal(nsIPrincipal* aPrincipal);
|
||||
|
||||
void
|
||||
SendActivityInternal(const nsACString& aOrigin);
|
||||
|
||||
void
|
||||
SendActivityToParent(nsIPrincipal* aPrincipal);
|
||||
|
||||
void
|
||||
MaybeStartTimer();
|
||||
|
||||
void
|
||||
MaybeStopTimer();
|
||||
|
||||
// Activities grouped by origin (+OriginAttributes).
|
||||
nsDataHashtable<nsCStringHashKey, PRTime> mActivities;
|
||||
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_StorageActivityService_h
|
@ -12,7 +12,6 @@ EXPORTS.mozilla.dom += [
|
||||
'LocalStorageManager.h',
|
||||
'SessionStorageManager.h',
|
||||
'Storage.h',
|
||||
'StorageActivityService.h',
|
||||
'StorageIPC.h',
|
||||
'StorageNotifierService.h',
|
||||
'StorageUtils.h',
|
||||
@ -26,7 +25,6 @@ UNIFIED_SOURCES += [
|
||||
'SessionStorageCache.cpp',
|
||||
'SessionStorageManager.cpp',
|
||||
'Storage.cpp',
|
||||
'StorageActivityService.cpp',
|
||||
'StorageDBThread.cpp',
|
||||
'StorageDBUpdater.cpp',
|
||||
'StorageIPC.cpp',
|
||||
|
@ -97,6 +97,8 @@ using namespace mozilla::ipc;
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
#define PURGE_DOMAIN_DATA "browser:purge-domain-data"
|
||||
#define PURGE_SESSION_HISTORY "browser:purge-session-history"
|
||||
#define CLEAR_ORIGIN_DATA "clear-origin-attributes-data"
|
||||
|
||||
static_assert(nsIHttpChannelInternal::CORS_MODE_SAME_ORIGIN == static_cast<uint32_t>(RequestMode::Same_origin),
|
||||
@ -286,6 +288,10 @@ ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar)
|
||||
|
||||
if (obs) {
|
||||
DebugOnly<nsresult> rv;
|
||||
rv = obs->AddObserver(this, PURGE_SESSION_HISTORY, false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = obs->AddObserver(this, PURGE_DOMAIN_DATA, false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = obs->AddObserver(this, CLEAR_ORIGIN_DATA, false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
@ -406,6 +412,8 @@ ServiceWorkerManager::MaybeStartShutdown()
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
obs->RemoveObserver(this, PURGE_SESSION_HISTORY);
|
||||
obs->RemoveObserver(this, PURGE_DOMAIN_DATA);
|
||||
obs->RemoveObserver(this, CLEAR_ORIGIN_DATA);
|
||||
}
|
||||
}
|
||||
@ -3547,6 +3555,14 @@ ServiceWorkerManager::ForceUnregister(RegistrationDataPerPrincipal* aRegistratio
|
||||
Unregister(aRegistration->mPrincipal, nullptr, NS_ConvertUTF8toUTF16(aRegistration->mScope));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::RemoveAndPropagate(const nsACString& aHost)
|
||||
{
|
||||
Remove(aHost);
|
||||
PropagateRemove(aHost);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::Remove(const nsACString& aHost)
|
||||
{
|
||||
@ -3659,6 +3675,20 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (strcmp(aTopic, PURGE_SESSION_HISTORY) == 0) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
RemoveAll();
|
||||
PropagateRemoveAll();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
nsAutoString domain(aData);
|
||||
RemoveAndPropagate(NS_ConvertUTF16toUTF8(domain));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (strcmp(aTopic, CLEAR_ORIGIN_DATA) == 0) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
OriginAttributesPattern pattern;
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/dom/StorageActivityService.h"
|
||||
#include "mozilla/ErrorNames.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
@ -259,7 +258,6 @@ ServiceWorkerRegistrar::RegisterServiceWorker(
|
||||
}
|
||||
|
||||
ScheduleSaveData();
|
||||
StorageActivityService::SendActivity(aData.principal());
|
||||
}
|
||||
|
||||
void
|
||||
@ -295,7 +293,6 @@ ServiceWorkerRegistrar::UnregisterServiceWorker(
|
||||
|
||||
if (deleted) {
|
||||
ScheduleSaveData();
|
||||
StorageActivityService::SendActivity(aPrincipalInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,26 +308,16 @@ ServiceWorkerRegistrar::RemoveAll()
|
||||
|
||||
bool deleted = false;
|
||||
|
||||
nsTArray<ServiceWorkerRegistrationData> data;
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mDataLoaded);
|
||||
|
||||
// Let's take a copy in order to inform StorageActivityService.
|
||||
data = mData;
|
||||
|
||||
deleted = !mData.IsEmpty();
|
||||
mData.Clear();
|
||||
}
|
||||
|
||||
if (!deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScheduleSaveData();
|
||||
|
||||
for (uint32_t i = 0, len = data.Length(); i < len; ++i) {
|
||||
StorageActivityService::SendActivity(data[i].principal());
|
||||
if (deleted) {
|
||||
ScheduleSaveData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
is(body, "intercepted", "Expected serviceworker to intercept request");
|
||||
});
|
||||
}).then(function() {
|
||||
return SpecialPowers.removeServiceWorkerDataForExampleDomain();
|
||||
SpecialPowers.removeServiceWorkerDataForExampleDomain();
|
||||
}).then(function() {
|
||||
return checkDomainRegistration("prefixexample.com", true /* exists */)
|
||||
.then(function(e) {
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "mozilla/dom/PGamepadTestChannelParent.h"
|
||||
#include "mozilla/dom/MessagePortParent.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrar.h"
|
||||
#include "mozilla/dom/StorageActivityService.h"
|
||||
#include "mozilla/dom/asmjscache/AsmJSCache.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/indexedDB/ActorsParent.h"
|
||||
@ -288,9 +287,6 @@ BackgroundParentImpl::RecvBroadcastLocalStorageChange(
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const bool& aIsPrivate)
|
||||
{
|
||||
// Let's inform the StorageActivityService about this change.
|
||||
dom::StorageActivityService::SendActivity(aPrincipalInfo);
|
||||
|
||||
nsTArray<PBackgroundParent*> liveActorArray;
|
||||
if (NS_WARN_IF(!BackgroundParent::GetLiveActorArray(this, liveActorArray))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
@ -991,13 +987,6 @@ BackgroundParentImpl::RecvPClientManagerConstructor(mozilla::dom::PClientManager
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult
|
||||
BackgroundParentImpl::RecvStorageActivity(const PrincipalInfo& aPrincipalInfo)
|
||||
{
|
||||
dom::StorageActivityService::SendActivity(aPrincipalInfo);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -271,9 +271,6 @@ protected:
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvPClientManagerConstructor(PClientManagerParent* aActor) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvStorageActivity(const PrincipalInfo& aPrincipalInfo) override;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
@ -140,10 +140,6 @@ parent:
|
||||
|
||||
async PClientManager();
|
||||
|
||||
// This method is used to propagate storage activities from the child actor
|
||||
// to the parent actor. See StorageActivityService.
|
||||
async StorageActivity(PrincipalInfo principalInfo);
|
||||
|
||||
child:
|
||||
async PCache();
|
||||
async PCacheStreamControl();
|
||||
|
@ -79,10 +79,6 @@
|
||||
#define SERVICEWORKERMANAGER_CID \
|
||||
{ 0xc74bde32, 0xbcc7, 0x4840, { 0x84, 0x30, 0xc7, 0x33, 0x35, 0x1b, 0x21, 0x2a } }
|
||||
|
||||
// {69da374a-fda3-4a93-9fbc-d9304f66a7fe}
|
||||
#define STORAGEACTIVITYSERVICE_CID \
|
||||
{ 0x69da374a, 0xfda3, 0x4a93, { 0x9f, 0xbc, 0xd9, 0x30, 0x4f, 0x66, 0xa7, 0xfe } }
|
||||
|
||||
#define NOTIFICATIONTELEMETRYSERVICE_CID \
|
||||
{ 0x5995b782, 0x6a0e, 0x4066, { 0xaa, 0xc5, 0x27, 0x6f, 0x0a, 0x9a, 0xd8, 0xcf } }
|
||||
|
||||
|
@ -83,7 +83,6 @@
|
||||
#include "mozilla/dom/network/UDPSocketChild.h"
|
||||
#include "mozilla/dom/quota/QuotaManagerService.h"
|
||||
#include "mozilla/dom/SessionStorageManager.h"
|
||||
#include "mozilla/dom/StorageActivityService.h"
|
||||
#include "mozilla/dom/workers/ServiceWorkerManager.h"
|
||||
#include "mozilla/dom/workers/WorkerDebuggerManager.h"
|
||||
#include "mozilla/dom/Notification.h"
|
||||
@ -253,8 +252,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ServiceWorkerManager,
|
||||
ServiceWorkerManager::GetInstance)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WorkerDebuggerManager,
|
||||
WorkerDebuggerManager::GetInstance)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(StorageActivityService,
|
||||
StorageActivityService::GetOrCreate)
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSynthVoiceRegistry,
|
||||
@ -628,7 +625,6 @@ NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID);
|
||||
NS_DEFINE_NAMED_CID(DOMREQUEST_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(QUOTAMANAGER_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(SERVICEWORKERMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(STORAGEACTIVITYSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NOTIFICATIONTELEMETRYSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(PUSHNOTIFIER_CID);
|
||||
NS_DEFINE_NAMED_CID(WORKERDEBUGGERMANAGER_CID);
|
||||
@ -886,7 +882,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
||||
{ &kDOMREQUEST_SERVICE_CID, false, nullptr, DOMRequestServiceConstructor },
|
||||
{ &kQUOTAMANAGER_SERVICE_CID, false, nullptr, QuotaManagerServiceConstructor },
|
||||
{ &kSERVICEWORKERMANAGER_CID, false, nullptr, ServiceWorkerManagerConstructor },
|
||||
{ &kSTORAGEACTIVITYSERVICE_CID, false, nullptr, StorageActivityServiceConstructor },
|
||||
{ &kNOTIFICATIONTELEMETRYSERVICE_CID, false, nullptr, NotificationTelemetryServiceConstructor },
|
||||
{ &kPUSHNOTIFIER_CID, false, nullptr, PushNotifierConstructor },
|
||||
{ &kWORKERDEBUGGERMANAGER_CID, true, nullptr, WorkerDebuggerManagerConstructor },
|
||||
@ -1012,7 +1007,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
||||
{ DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID },
|
||||
{ QUOTAMANAGER_SERVICE_CONTRACTID, &kQUOTAMANAGER_SERVICE_CID },
|
||||
{ SERVICEWORKERMANAGER_CONTRACTID, &kSERVICEWORKERMANAGER_CID },
|
||||
{ STORAGE_ACTIVITY_SERVICE_CONTRACTID, &kSTORAGEACTIVITYSERVICE_CID },
|
||||
{ NOTIFICATIONTELEMETRYSERVICE_CONTRACTID, &kNOTIFICATIONTELEMETRYSERVICE_CID },
|
||||
{ PUSHNOTIFIER_CONTRACTID, &kPUSHNOTIFIER_CID },
|
||||
{ WORKERDEBUGGERMANAGER_CONTRACTID, &kWORKERDEBUGGERMANAGER_CID },
|
||||
|
@ -23,7 +23,6 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
|
||||
// We're loaded with "this" not set to the global in some cases, so we
|
||||
// have to play some games to get at the global object here. Normally
|
||||
@ -1957,11 +1956,11 @@ SpecialPowersAPI.prototype = {
|
||||
},
|
||||
|
||||
removeAllServiceWorkerData() {
|
||||
return wrapIfUnwrapped(ServiceWorkerCleanUp.removeAll());
|
||||
this.notifyObserversInParentProcess(null, "browser:purge-session-history", "");
|
||||
},
|
||||
|
||||
removeServiceWorkerDataForExampleDomain() {
|
||||
return wrapIfUnwrapped(ServiceWorkerCleanUp.removeFromHost("example.com"));
|
||||
this.notifyObserversInParentProcess(null, "browser:purge-domain-data", "example.com");
|
||||
},
|
||||
|
||||
cleanUpSTSData(origin, flags) {
|
||||
|
@ -11,8 +11,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ServiceWorkerCleanUp",
|
||||
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ForgetAboutSite"];
|
||||
|
||||
@ -148,11 +146,7 @@ this.ForgetAboutSite = {
|
||||
}));
|
||||
}
|
||||
|
||||
// ServiceWorkers
|
||||
await ServiceWorkerCleanUp.removeFromHost("http://" + aDomain);
|
||||
await ServiceWorkerCleanUp.removeFromHost("https://" + aDomain);
|
||||
|
||||
// Offline Storages. This must run after the ServiceWorkers promises.
|
||||
// Offline Storages
|
||||
promises.push((async function() {
|
||||
// delete data from both HTTP and HTTPS sites
|
||||
let httpURI = NetUtil.newURI("http://" + aDomain);
|
||||
|
@ -1,62 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
"nsIServiceWorkerManager");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ServiceWorkerCleanUp"];
|
||||
|
||||
function unregisterServiceWorker(aSW) {
|
||||
return new Promise(resolve => {
|
||||
let unregisterCallback = {
|
||||
unregisterSucceeded: resolve,
|
||||
unregisterFailed: resolve, // We don't care about failures.
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIServiceWorkerUnregisterCallback])
|
||||
};
|
||||
serviceWorkerManager.propagateUnregister(aSW.principal, unregisterCallback, aSW.scope);
|
||||
});
|
||||
}
|
||||
|
||||
this.ServiceWorkerCleanUp = {
|
||||
removeFromHost(aHost) {
|
||||
let promises = [];
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
if (sw.principal.URI.host == aHost) {
|
||||
promises.push(unregisterServiceWorker(sw));
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
removeFromPrincipal(aPrincipal) {
|
||||
let promises = [];
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
if (sw.principal.equals(aPrincipal)) {
|
||||
promises.push(unregisterServiceWorker(sw));
|
||||
}
|
||||
}
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
removeAll() {
|
||||
let promises = [];
|
||||
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
|
||||
for (let i = 0; i < serviceWorkers.length; i++) {
|
||||
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
||||
promises.push(unregisterServiceWorker(sw));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
},
|
||||
};
|
@ -9,7 +9,6 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'ForgetAboutSite.jsm',
|
||||
'ServiceWorkerCleanUp.jsm',
|
||||
]
|
||||
|
||||
with Files('**'):
|
||||
|
Loading…
Reference in New Issue
Block a user