commit 46008ce7aa7373043632bb07a183d3685bcae705 Author: Alex Catarineu acat@torproject.org Date: Fri Sep 4 12:34:35 2020 +0200
Bug 40091: Load HTTPS Everywhere as a builtin addon in desktop
This loads HTTPS Everywhere as a builtin addon from a hardcoded resource:// URI in desktop. It also ensures that the non-builtin HTTPS Everywhere addon is always uninstalled on browser startup.
The reason of making this desktop-only is that there are some issues when installing a builtin extension from geckoview side, making the extension not available on first startup. So, at least for now we handle the Fenix case separately. See #40118 for a followup for investigating these. --- browser/components/BrowserGlue.jsm | 37 ++++++++++++++++++++++ toolkit/components/extensions/Extension.jsm | 14 ++++++-- .../mozapps/extensions/internal/XPIProvider.jsm | 13 ++++++++ 3 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index ec38d0ca8b33..057a2121533c 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -56,6 +56,13 @@ XPCOMUtils.defineLazyServiceGetter( "nsIPushService" );
+XPCOMUtils.defineLazyServiceGetters(this, { + resProto: [ + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler", + ], +}); + const PREF_PDFJS_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state";
/** @@ -675,6 +682,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { "resource://gre/modules/ContextualIdentityService.jsm", Corroborate: "resource://gre/modules/Corroborate.jsm", Discovery: "resource:///modules/Discovery.jsm", + ExtensionData: "resource://gre/modules/Extension.jsm", ExtensionsUI: "resource:///modules/ExtensionsUI.jsm", FirefoxMonitor: "resource:///modules/FirefoxMonitor.jsm", FxAccounts: "resource://gre/modules/FxAccounts.jsm", @@ -1330,6 +1338,35 @@ BrowserGlue.prototype = { "resource:///modules/themes/dark/" );
+ // Install https-everywhere builtin addon if needed. + (async () => { + const HTTPS_EVERYWHERE_ID = "https-everywhere-eff@eff.org"; + const HTTPS_EVERYWHERE_BUILTIN_URL = + "resource://torbutton/content/extensions/https-everywhere/"; + // This does something similar as GeckoViewWebExtension.jsm: it tries + // to load the manifest to retrieve the version of the builtin and + // compares it to the currently installed one to see whether we need + // to install or not. Here we delegate that to + // AddonManager.maybeInstallBuiltinAddon. + try { + const resolvedURI = Services.io.newURI( + resProto.resolveURI(Services.io.newURI(HTTPS_EVERYWHERE_BUILTIN_URL)) + ); + const extensionData = new ExtensionData(resolvedURI); + const manifest = await extensionData.loadManifest(); + + await AddonManager.maybeInstallBuiltinAddon( + HTTPS_EVERYWHERE_ID, + manifest.version, + HTTPS_EVERYWHERE_BUILTIN_URL + ); + } catch (e) { + const log = Log.repository.getLogger("HttpsEverywhereBuiltinLoader"); + log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter())); + log.error("Could not install https-everywhere extension", e); + } + })(); + if (AppConstants.MOZ_NORMANDY) { Normandy.init(); } diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index 876e636be3db..7dbd888b1710 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -211,6 +211,7 @@ const LOGGER_ID_BASE = "addons.webextension."; const UUID_MAP_PREF = "extensions.webextensions.uuids"; const LEAVE_STORAGE_PREF = "extensions.webextensions.keepStorageOnUninstall"; const LEAVE_UUID_PREF = "extensions.webextensions.keepUuidOnUninstall"; +const PERSISTENT_EXTENSIONS = new Set(["https-everywhere-eff@eff.org"]);
const COMMENT_REGEXP = new RegExp( String.raw` @@ -331,7 +332,10 @@ var ExtensionAddonObserver = { return; }
- if (!Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false)) { + if ( + !Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false) && + !PERSISTENT_EXTENSIONS.has(addon.id) + ) { // Clear browser.storage.local backends. AsyncShutdown.profileChangeTeardown.addBlocker( `Clear Extension Storage ${addon.id} (File Backend)`, @@ -384,7 +388,10 @@ var ExtensionAddonObserver = {
ExtensionPermissions.removeAll(addon.id);
- if (!Services.prefs.getBoolPref(LEAVE_UUID_PREF, false)) { + if ( + !Services.prefs.getBoolPref(LEAVE_UUID_PREF, false) && + !PERSISTENT_EXTENSIONS.has(addon.id) + ) { // Clear the entry in the UUID map UUIDMap.remove(addon.id); } @@ -2474,7 +2481,8 @@ class Extension extends ExtensionData { ); } else if ( this.startupReason === "ADDON_INSTALL" && - !Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false) + !Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false) && + !PERSISTENT_EXTENSIONS.has(this.id) ) { // If the extension has been just installed, set it as migrated, // because there will not be any data to migrate. diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 794c206fb453..dc5362bce3d8 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -1491,6 +1491,19 @@ var XPIStates = { continue; }
+ // Uninstall HTTPS Everywhere if it is installed in the user profile. + if ( + id === "https-everywhere-eff@eff.org" && + loc.name === KEY_APP_PROFILE + ) { + logger.debug( + "Uninstalling the HTTPS Everywhere extension from user profile." + ); + loc.installer.uninstallAddon(id); + changed = true; + continue; + } + let xpiState = loc.get(id); if (!xpiState) { // If the location is not supported for sideloading, skip new
tor-commits@lists.torproject.org