--- a/browser/modules/Sanitizer.jsm
+++ b/browser/modules/Sanitizer.jsm
@@ -270,16 +270,20 @@ var Sanitizer = {
}
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsiObserver,
Ci.nsISupportsWeakReference
]),
+ // When making any changes to the sanitize implementations here,
+ // please check whether the changes are applicable to Android
+ // (mobile/android/modules/Sanitizer.jsm) as well.
+
items: {
cache: {
async clear(range) {
let seenException;
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_CACHE", refObj);
try {
--- a/mobile/android/modules/Sanitizer.jsm
+++ b/mobile/android/modules/Sanitizer.jsm
@@ -62,17 +62,26 @@ Sanitizer.prototype = {
}
};
return maybeDoClear();
} else if (canClear) {
return item.clear(options);
}
},
+ // This code is mostly based on the Sanitizer code for desktop Firefox
+ // (browser/modules/Sanitzer.jsm), however over the course of time some
+ // general differences have evolved:
+ // - async shutdown (and seenException handling) isn't implemented in Fennec
+ // - currently there is only limited support for range-based clearing of data
+
+ // Any further specific differences caused by architectural differences between
+ // Fennec and desktop Firefox are documented below for each item.
items: {
+ // Same as desktop Firefox.
cache: {
clear: function() {
return new Promise(function(resolve, reject) {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_CACHE", refObj);
try {
Services.cache2.clear();
@@ -89,16 +98,18 @@ Sanitizer.prototype = {
});
},
get canClear() {
return true;
}
},
+ // Compared to desktop, we don't clear plugin data, as plugins
+ // aren't supported on Android.
cookies: {
clear: function() {
return new Promise(function(resolve, reject) {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_COOKIES_2", refObj);
Services.cookies.removeAll();
@@ -115,16 +126,17 @@ Sanitizer.prototype = {
});
},
get canClear() {
return true;
}
},
+ // Same as desktop Firefox.
siteSettings: {
clear: Task.async(function* () {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_SITESETTINGS", refObj);
// Clear site-specific permissions like "Allow this site to open popups"
Services.perms.removeAll();
@@ -154,16 +166,17 @@ Sanitizer.prototype = {
TelemetryStopwatch.finish("FX_SANITIZE_SITESETTINGS", refObj);
}),
get canClear() {
return true;
}
},
+ // Same as desktop Firefox.
offlineApps: {
async clear() {
// AppCache
// This doesn't wait for the cleanup to be complete.
OfflineAppCacheHelper.clear();
// LocalStorage
Services.obs.notifyObservers(null, "extension:purge-localStorage");
@@ -199,16 +212,18 @@ Sanitizer.prototype = {
return Promise.all(promises);
},
get canClear() {
return true;
}
},
+ // History on Android is implemented by the Java frontend and requires
+ // different handling. Everything else is the same as for desktop Firefox.
history: {
clear: function() {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_HISTORY", refObj);
return EventDispatcher.instance.sendRequestForResult({ type: "Sanitize:ClearHistory" })
.catch(e => Cu.reportError("Java-side history clearing failed: " + e))
.then(function() {
@@ -226,16 +241,18 @@ Sanitizer.prototype = {
get canClear() {
// bug 347231: Always allow clearing history due to dependencies on
// the browser:purge-session-history notification. (like error console)
return true;
}
},
+ // Equivalent to openWindows on desktop, but specific to Fennec's implementation
+ // of tabbed browsing and the session store.
openTabs: {
clear: function() {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_OPENWINDOWS", refObj);
return EventDispatcher.instance.sendRequestForResult({ type: "Sanitize:OpenTabs" })
.catch(e => Cu.reportError("Java-side tab clearing failed: " + e))
.then(function() {
@@ -247,27 +264,30 @@ Sanitizer.prototype = {
});
},
get canClear() {
return true;
}
},
+ // Specific to Fennec.
searchHistory: {
clear: function() {
return EventDispatcher.instance.sendRequestForResult({ type: "Sanitize:ClearHistory", clearSearchHistory: true })
.catch(e => Cu.reportError("Java-side search history clearing failed: " + e));
},
get canClear() {
return true;
}
},
+ // Browser search is handled by searchHistory above and the find bar doesn't
+ // require extra handling. FormHistory itself is cleared like on desktop.
formdata: {
clear: function({ startTime = 0 } = {}) {
return new Promise(function(resolve, reject) {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_FORMDATA", refObj);
// Conver time to microseconds
let time = startTime * 1000;
@@ -289,16 +309,17 @@ Sanitizer.prototype = {
handleResult: function(aResult) { count = aResult; },
handleError: function(aError) { Cu.reportError(aError); },
handleCompletion: function(aReason) { aCallback(aReason == 0 && count > 0); }
};
FormHistory.count({}, countDone);
}
},
+ // Adapted from desktop, but heavily modified - see comments below.
downloadFiles: {
clear: Task.async(function* ({ startTime = 0, deleteFiles = true} = {}) {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_DOWNLOADS", refObj);
let list = yield Downloads.getList(Downloads.ALL);
let downloads = yield list.getAll();
var finalizePromises = [];
@@ -338,30 +359,32 @@ Sanitizer.prototype = {
TelemetryStopwatch.finish("FX_SANITIZE_DOWNLOADS", refObj);
}),
get canClear() {
return true;
}
},
+ // Specific to Fennec.
passwords: {
clear: function() {
return new Promise(function(resolve, reject) {
Services.logins.removeAllLogins();
resolve();
});
},
get canClear() {
let count = Services.logins.countLogins("", "", ""); // count all logins
return (count > 0);
}
},
+ // Same as desktop Firefox.
sessions: {
clear: function() {
return new Promise(function(resolve, reject) {
let refObj = {};
TelemetryStopwatch.start("FX_SANITIZE_SESSIONS", refObj);
// clear all auth tokens
var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
@@ -375,16 +398,17 @@ Sanitizer.prototype = {
});
},
get canClear() {
return true;
}
},
+ // Specific to Fennec.
syncedTabs: {
clear: function() {
return EventDispatcher.instance.sendRequestForResult({ type: "Sanitize:ClearSyncedTabs" })
.catch(e => Cu.reportError("Java-side synced tabs clearing failed: " + e));
},
canClear: function(aCallback) {
Accounts.anySyncAccountsExist().then(aCallback)