зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1252998 - StorageActivityService - part 4 - Introduce ServiceWorkerCleanUp.jsm to clean up ServiceWorker data, r=asuth
This commit is contained in:
Родитель
770b7bb21e
Коммит
c3b61ca1bf
|
@ -13,6 +13,8 @@ ChromeUtils.defineModuleGetter(this, "Services",
|
|||
"resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "setTimeout",
|
||||
"resource://gre/modules/Timer.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "ServiceWorkerCleanUp",
|
||||
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
|
@ -145,22 +147,6 @@ 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)) {
|
||||
|
@ -201,7 +187,7 @@ const doRemoval = (options, dataToRemove, extension) => {
|
|||
removalPromises.push(clearPluginData(options));
|
||||
break;
|
||||
case "serviceWorkers":
|
||||
removalPromises.push(clearServiceWorkers());
|
||||
removalPromises.push(ServiceWorkerCleanUp.removeAll());
|
||||
break;
|
||||
default:
|
||||
invalidDataTypes.push(dataType);
|
||||
|
|
|
@ -16,11 +16,9 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
DownloadsCommon: "resource:///modules/DownloadsCommon.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
"nsIServiceWorkerManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "quotaManagerService",
|
||||
"@mozilla.org/dom/quota-manager-service;1",
|
||||
"nsIQuotaManagerService");
|
||||
|
@ -373,28 +371,10 @@ var Sanitizer = {
|
|||
Services.obs.notifyObservers(null, "extension:purge-localStorage");
|
||||
|
||||
// ServiceWorkers
|
||||
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);
|
||||
await ServiceWorkerCleanUp.removeAll();
|
||||
|
||||
// QuotaManager
|
||||
promises = [];
|
||||
let promises = [];
|
||||
await new Promise(resolve => {
|
||||
quotaManagerService.getUsage(request => {
|
||||
if (request.resultCode != Cr.NS_OK) {
|
||||
|
|
|
@ -5,9 +5,8 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
|
||||
ChromeUtils.defineModuleGetter(this, "OfflineAppCacheHelper",
|
||||
"resource:///modules/offlineAppCache.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
|
||||
"@mozilla.org/serviceworkers/manager;1",
|
||||
"nsIServiceWorkerManager");
|
||||
ChromeUtils.defineModuleGetter(this, "ServiceWorkerCleanUp",
|
||||
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"SiteDataManager"
|
||||
|
@ -315,27 +314,11 @@ var SiteDataManager = {
|
|||
site.cookies = [];
|
||||
},
|
||||
|
||||
_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 = [];
|
||||
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 (sites.has(sw.principal.URI.host)) {
|
||||
promises.push(this._unregisterServiceWorker(sw));
|
||||
}
|
||||
}
|
||||
sites.forEach(s => {
|
||||
promises.push(ServiceWorkerCleanUp.removeFromHost(s.principals[0].URI.host));
|
||||
});
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
|
@ -448,14 +431,7 @@ var SiteDataManager = {
|
|||
Services.cookies.removeAll();
|
||||
OfflineAppCacheHelper.clear();
|
||||
|
||||
// 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);
|
||||
await ServiceWorkerCleanUp.removeAll();
|
||||
|
||||
// Refresh sites using quota usage again.
|
||||
// This is for the case:
|
||||
|
@ -469,7 +445,7 @@ var SiteDataManager = {
|
|||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1312361#c9
|
||||
this._sites.clear();
|
||||
await this._getQuotaUsage();
|
||||
promises = [];
|
||||
let promises = [];
|
||||
for (let site of this._sites.values()) {
|
||||
this._removePermission(site);
|
||||
promises.push(this._removeQuotaUsage(site));
|
||||
|
|
|
@ -144,17 +144,6 @@ interface nsIServiceWorkerManager : nsISupports
|
|||
[notxpcom, nostdcall] bool StartControlling(in const_ClientInfoRef aClientInfo,
|
||||
in const_ServiceWorkerDescriptorRef aServiceWorker);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
|
|
@ -100,7 +100,6 @@ using namespace mozilla::ipc;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
#define PURGE_DOMAIN_DATA "browser:purge-domain-data"
|
||||
#define CLEAR_ORIGIN_DATA "clear-origin-attributes-data"
|
||||
|
||||
static_assert(nsIHttpChannelInternal::CORS_MODE_SAME_ORIGIN == static_cast<uint32_t>(RequestMode::Same_origin),
|
||||
|
@ -291,8 +290,6 @@ ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar)
|
|||
|
||||
if (obs) {
|
||||
DebugOnly<nsresult> 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));
|
||||
}
|
||||
|
@ -413,7 +410,6 @@ ServiceWorkerManager::MaybeStartShutdown()
|
|||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
obs->RemoveObserver(this, PURGE_DOMAIN_DATA);
|
||||
obs->RemoveObserver(this, CLEAR_ORIGIN_DATA);
|
||||
}
|
||||
}
|
||||
|
@ -3059,14 +3055,6 @@ ServiceWorkerManager::ForceUnregister(RegistrationDataPerPrincipal* aRegistratio
|
|||
Unregister(aRegistration->Principal(), nullptr, NS_ConvertUTF8toUTF16(aRegistration->Scope()));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::RemoveAndPropagate(const nsACString& aHost)
|
||||
{
|
||||
Remove(aHost);
|
||||
PropagateRemove(aHost);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::Remove(const nsACString& aHost)
|
||||
{
|
||||
|
@ -3179,13 +3167,6 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
|
|||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
is(body, "intercepted", "Expected serviceworker to intercept request");
|
||||
});
|
||||
}).then(function() {
|
||||
SpecialPowers.removeServiceWorkerDataForExampleDomain();
|
||||
return SpecialPowers.removeServiceWorkerDataForExampleDomain();
|
||||
}).then(function() {
|
||||
return checkDomainRegistration("prefixexample.com", true /* exists */)
|
||||
.then(function(e) {
|
||||
|
|
|
@ -20,6 +20,7 @@ ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.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
|
||||
|
@ -1961,11 +1962,11 @@ SpecialPowersAPI.prototype = {
|
|||
},
|
||||
|
||||
removeAllServiceWorkerData() {
|
||||
this.notifyObserversInParentProcess(null, "browser:purge-session-history", "");
|
||||
return wrapIfUnwrapped(ServiceWorkerCleanUp.removeAll());
|
||||
},
|
||||
|
||||
removeServiceWorkerDataForExampleDomain() {
|
||||
this.notifyObserversInParentProcess(null, "browser:purge-domain-data", "example.com");
|
||||
return wrapIfUnwrapped(ServiceWorkerCleanUp.removeFromHost("example.com"));
|
||||
},
|
||||
|
||||
cleanUpSTSData(origin, flags) {
|
||||
|
|
|
@ -11,6 +11,8 @@ ChromeUtils.defineModuleGetter(this, "PlacesUtils",
|
|||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "ServiceWorkerCleanUp",
|
||||
"resource://gre/modules/ServiceWorkerCleanUp.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ForgetAboutSite"];
|
||||
|
||||
|
@ -142,7 +144,11 @@ var ForgetAboutSite = {
|
|||
}));
|
||||
}
|
||||
|
||||
// Offline Storages
|
||||
// ServiceWorkers
|
||||
await ServiceWorkerCleanUp.removeFromHost("http://" + aDomain);
|
||||
await ServiceWorkerCleanUp.removeFromHost("https://" + aDomain);
|
||||
|
||||
// Offline Storages. This must run after the ServiceWorkers promises.
|
||||
promises.push((async function() {
|
||||
// delete data from both HTTP and HTTPS sites
|
||||
let httpURI = NetUtil.newURI("http://" + aDomain);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/* 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";
|
||||
|
||||
ChromeUtils.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);
|
||||
},
|
||||
|
||||
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,6 +9,7 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
|||
|
||||
EXTRA_JS_MODULES += [
|
||||
'ForgetAboutSite.jsm',
|
||||
'ServiceWorkerCleanUp.jsm',
|
||||
]
|
||||
|
||||
with Files('**'):
|
||||
|
|
Загрузка…
Ссылка в новой задаче