зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1422365 - Introduce nsIClearDataService - part 3 - plugin data, r=johannh
This commit is contained in:
Родитель
f42b9d4e33
Коммит
7a1184f9d6
|
@ -14,7 +14,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
FormHistory: "resource://gre/modules/FormHistory.jsm",
|
||||
Downloads: "resource://gre/modules/Downloads.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm",
|
||||
OfflineAppCacheHelper: "resource://gre/modules/offlineAppCache.jsm",
|
||||
ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
|
||||
|
@ -325,33 +324,18 @@ var Sanitizer = {
|
|||
|
||||
cookies: {
|
||||
async clear(range) {
|
||||
let seenException;
|
||||
let refObj = {};
|
||||
|
||||
// Clear cookies.
|
||||
// Clear cookies and plugin data.
|
||||
TelemetryStopwatch.start("FX_SANITIZE_COOKIES_2", refObj);
|
||||
await clearData(range, Ci.nsIClearDataService.CLEAR_COOKIES);
|
||||
await clearData(range, Ci.nsIClearDataService.CLEAR_COOKIES |
|
||||
Ci.nsIClearDataService.CLEAR_PLUGIN_DATA);
|
||||
TelemetryStopwatch.finish("FX_SANITIZE_COOKIES_2", refObj);
|
||||
|
||||
// Clear deviceIds. Done asynchronously (returns before complete).
|
||||
try {
|
||||
let mediaMgr = Cc["@mozilla.org/mediaManagerService;1"]
|
||||
.getService(Ci.nsIMediaManagerService);
|
||||
mediaMgr.sanitizeDeviceIds(range && range[0]);
|
||||
} catch (ex) {
|
||||
seenException = ex;
|
||||
}
|
||||
|
||||
// Clear plugin data.
|
||||
try {
|
||||
await clearPluginData(range);
|
||||
} catch (ex) {
|
||||
seenException = ex;
|
||||
}
|
||||
|
||||
if (seenException) {
|
||||
throw seenException;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -772,7 +756,7 @@ var Sanitizer = {
|
|||
|
||||
pluginData: {
|
||||
async clear(range) {
|
||||
await clearPluginData(range);
|
||||
await clearData(range, Ci.nsIClearDataService.CLEAR_PLUGIN_DATA);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -862,70 +846,6 @@ async function sanitizeInternal(items, aItemsToClear, progress, options = {}) {
|
|||
}
|
||||
}
|
||||
|
||||
async function clearPluginData(range) {
|
||||
// Clear plugin data.
|
||||
// As evidenced in bug 1253204, clearing plugin data can sometimes be
|
||||
// very, very long, for mysterious reasons. Unfortunately, this is not
|
||||
// something actionable by Mozilla, so crashing here serves no purpose.
|
||||
//
|
||||
// For this reason, instead of waiting for sanitization to always
|
||||
// complete, we introduce a soft timeout. Once this timeout has
|
||||
// elapsed, we proceed with the shutdown of Firefox.
|
||||
let seenException;
|
||||
|
||||
let promiseClearPluginData = async function() {
|
||||
const FLAG_CLEAR_ALL = Ci.nsIPluginHost.FLAG_CLEAR_ALL;
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
|
||||
// Determine age range in seconds. (-1 means clear all.) We don't know
|
||||
// that range[1] is actually now, so we compute age range based
|
||||
// on the lower bound. If range results in a negative age, do nothing.
|
||||
let age = range ? (Date.now() / 1000 - range[0] / 1000000) : -1;
|
||||
if (!range || age >= 0) {
|
||||
let tags = ph.getPluginTags();
|
||||
for (let tag of tags) {
|
||||
try {
|
||||
let rv = await new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, age, resolve)
|
||||
);
|
||||
// If the plugin doesn't support clearing by age, clear everything.
|
||||
if (rv == Cr.NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED) {
|
||||
await new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, -1, resolve)
|
||||
);
|
||||
}
|
||||
} catch (ex) {
|
||||
// Ignore errors from plug-ins
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// We don't want to wait for this operation to complete...
|
||||
promiseClearPluginData = promiseClearPluginData(range);
|
||||
|
||||
// ... at least, not for more than 10 seconds.
|
||||
await Promise.race([
|
||||
promiseClearPluginData,
|
||||
new Promise(resolve => setTimeout(resolve, 10000 /* 10 seconds */))
|
||||
]);
|
||||
} catch (ex) {
|
||||
seenException = ex;
|
||||
}
|
||||
|
||||
// Detach waiting for plugin data to be cleared.
|
||||
promiseClearPluginData.catch(() => {
|
||||
// If this exception is raised before the soft timeout, it
|
||||
// will appear in `seenException`. Otherwise, it's too late
|
||||
// to do anything about it.
|
||||
});
|
||||
|
||||
if (seenException) {
|
||||
throw seenException;
|
||||
}
|
||||
}
|
||||
|
||||
async function sanitizeOnShutdown(progress) {
|
||||
if (Sanitizer.shouldSanitizeOnShutdown) {
|
||||
// Need to sanitize upon shutdown
|
||||
|
|
|
@ -89,6 +89,88 @@ const ImageCacheCleaner = {
|
|||
},
|
||||
};
|
||||
|
||||
const PluginDataCleaner = {
|
||||
deleteByHost(aHost, aOriginAttributes) {
|
||||
return this._deleteInternal((aPh, aTag) => {
|
||||
return new Promise(aResolve => {
|
||||
try {
|
||||
aPh.clearSiteData(aTag, aHost,
|
||||
Ci.nsIPluginHost.FLAG_CLEAR_ALL,
|
||||
-1, aResolve);
|
||||
} catch (e) {
|
||||
// Ignore errors from the plugin, but resolve the promise
|
||||
// We cannot check if something is a bailout or an error
|
||||
aResolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
deleteByRange(aFrom, aTo) {
|
||||
let age = Date.now() / 1000 - aFrom / 1000000;
|
||||
|
||||
return this._deleteInternal((aPh, aTag) => {
|
||||
return new Promise(aResolve => {
|
||||
try {
|
||||
aPh.clearSiteData(aTag, null, Ci.nsIPluginHost.FLAG_CLEAR_ALL,
|
||||
age, aResolve);
|
||||
} catch (e) {
|
||||
aResolve(Cr.NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED);
|
||||
}
|
||||
}).then(aRv => {
|
||||
// If the plugin doesn't support clearing by age, clear everything.
|
||||
if (aRv == Cr.NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED) {
|
||||
return new Promise(aResolve => {
|
||||
try {
|
||||
aPh.clearSiteData(aTag, null, Ci.nsIPluginHost.FLAG_CLEAR_ALL,
|
||||
-1, aResolve);
|
||||
} catch (e) {
|
||||
aResolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
deleteAll() {
|
||||
return this._deleteInternal((aPh, aTag) => {
|
||||
return new Promise(aResolve => {
|
||||
try {
|
||||
aPh.clearSiteData(aTag, null, Ci.nsIPluginHost.FLAG_CLEAR_ALL, -1,
|
||||
aResolve);
|
||||
} catch (e) {
|
||||
aResolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_deleteInternal(aCb) {
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
|
||||
let promises = [];
|
||||
let tags = ph.getPluginTags();
|
||||
for (let tag of tags) {
|
||||
promises.push(aCb(ph, tag));
|
||||
}
|
||||
|
||||
// As evidenced in bug 1253204, clearing plugin data can sometimes be
|
||||
// very, very long, for mysterious reasons. Unfortunately, this is not
|
||||
// something actionable by Mozilla, so crashing here serves no purpose.
|
||||
//
|
||||
// For this reason, instead of waiting for sanitization to always
|
||||
// complete, we introduce a soft timeout. Once this timeout has
|
||||
// elapsed, we proceed with the shutdown of Firefox.
|
||||
return Promise.race([
|
||||
Promise.all(promises),
|
||||
new Promise(aResolve => setTimeout(aResolve, 10000 /* 10 seconds */))
|
||||
]);
|
||||
},
|
||||
};
|
||||
|
||||
// Here the map of Flags-Cleaner.
|
||||
const FLAGS_MAP = [
|
||||
{ flag: Ci.nsIClearDataService.CLEAR_COOKIES,
|
||||
|
@ -99,6 +181,9 @@ const FLAGS_MAP = [
|
|||
|
||||
{ flag: Ci.nsIClearDataService.CLEAR_IMAGE_CACHE,
|
||||
cleaner: ImageCacheCleaner, },
|
||||
|
||||
{ flag: Ci.nsIClearDataService.CLEAR_PLUGIN_DATA,
|
||||
cleaner: PluginDataCleaner, },
|
||||
];
|
||||
|
||||
this.ClearDataService = function() {};
|
||||
|
|
|
@ -98,9 +98,13 @@ interface nsIClearDataService : nsISupports
|
|||
*/
|
||||
const uint32_t CLEAR_IMAGE_CACHE = 1 << 2;
|
||||
|
||||
/**
|
||||
* Data stored by external plugins.
|
||||
*/
|
||||
const uint32_t CLEAR_PLUGIN_DATA = 1 << 3;
|
||||
|
||||
/* TODO
|
||||
const uint32_t CLEAR_EME = 1 << 3;
|
||||
const uint32_t CLEAR_PLUGIN_DATA = 1 << 4;
|
||||
const uint32_t CLEAR_EME = 1 << 4;
|
||||
const uint32_t CLEAR_DOWNLOADS = 1 << 5;
|
||||
const uint32_t CLEAR_PASSWORDS = 1 << 6;
|
||||
const uint32_t CLEAR_PERMISSIONS = 1 << 7;
|
||||
|
|
|
@ -13,8 +13,7 @@ add_task(async function test_basic() {
|
|||
Assert.ok(!!service);
|
||||
|
||||
await new Promise(aResolve => {
|
||||
service.deleteData(Ci.nsIClearDataService.CLEAR_IMAGE_CACHE |
|
||||
Ci.nsIClearDataService.CLEAR_COOKIES, value => {
|
||||
service.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => {
|
||||
Assert.equal(value, 0);
|
||||
aResolve();
|
||||
});
|
||||
|
|
|
@ -64,23 +64,6 @@ var ForgetAboutSite = {
|
|||
}));
|
||||
|
||||
|
||||
// Plugin data
|
||||
const phInterface = Ci.nsIPluginHost;
|
||||
const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
|
||||
let tags = ph.getPluginTags();
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
promises.push(new Promise(resolve => {
|
||||
try {
|
||||
ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1, resolve);
|
||||
} catch (e) {
|
||||
// Ignore errors from the plugin, but resolve the promise
|
||||
// We cannot check if something is a bailout or an error
|
||||
resolve();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// Downloads
|
||||
promises.push((async function() {
|
||||
let list = await Downloads.getList(Downloads.ALL);
|
||||
|
|
Загрузка…
Ссылка в новой задаче