diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 1bf374a6b7ec..780c869c7ff5 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -77,7 +77,7 @@ pref("extensions.update.autoUpdateDefault", true); // Disable add-ons installed into the shared user and shared system areas by // default. This does not include the application directory. See the SCOPE // constants in AddonManager.jsm for values to use here -pref("extensions.autoDisableScopes", 10); +pref("extensions.autoDisableScopes", 15); // Dictionary download preference pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/"); diff --git a/build/automation.py.in b/build/automation.py.in index 047c9185345e..4680f7e4b1a5 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -433,6 +433,8 @@ user_pref("toolkit.telemetry.prompted", true); // Only load extensions from the application and user profile // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION user_pref("extensions.enabledScopes", 5); +// Allow dropped in extensions in the application and user profile +user_pref("extensions.autoDisableScopes", 10); // Disable metadata caching for installed add-ons by default user_pref("extensions.getAddons.cache.enabled", false); // Disable intalling any distribution add-ons diff --git a/toolkit/mozapps/extensions/LightweightThemeManager.jsm b/toolkit/mozapps/extensions/LightweightThemeManager.jsm index 63ac4db23635..29b29be6b797 100644 --- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm +++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm @@ -556,6 +556,10 @@ AddonWrapper.prototype = { return AddonManager.SCOPE_PROFILE; }, + get foreignInstall() { + return false; + }, + // Lightweight themes are always compatible isCompatibleWith: function(appVersion, platformVersion) { return true; diff --git a/toolkit/mozapps/extensions/PluginProvider.jsm b/toolkit/mozapps/extensions/PluginProvider.jsm index e69efc10243d..6545a9fcb832 100644 --- a/toolkit/mozapps/extensions/PluginProvider.jsm +++ b/toolkit/mozapps/extensions/PluginProvider.jsm @@ -339,6 +339,10 @@ PluginWrapper.prototype = { return true; }, + get foreignInstall() { + return true; + }, + isCompatibleWith: function(aAppVerison, aPlatformVersion) { return true; }, diff --git a/toolkit/mozapps/extensions/XPIProvider.jsm b/toolkit/mozapps/extensions/XPIProvider.jsm index e75d3ba0617e..ad6816e54215 100644 --- a/toolkit/mozapps/extensions/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/XPIProvider.jsm @@ -122,7 +122,7 @@ const TOOLKIT_ID = "toolkit@mozilla.org"; const BRANCH_REGEXP = /^([^\.]+\.[0-9]+[a-z]*).*/gi; -const DB_SCHEMA = 5; +const DB_SCHEMA = 6; const REQ_VERSION = 2; #ifdef MOZ_COMPATIBILITY_NIGHTLY @@ -146,7 +146,7 @@ const DB_METADATA = ["installDate", "updateDate", "size", "sourceURI", "releaseNotesURI", "applyBackgroundUpdates"]; const DB_BOOL_METADATA = ["visible", "active", "userDisabled", "appDisabled", "pendingUninstall", "bootstrap", "skinnable", - "softDisabled"]; + "softDisabled", "foreignInstall"]; const BOOTSTRAP_REASONS = { APP_STARTUP : 1, @@ -2556,10 +2556,16 @@ var XPIProvider = { newAddon = aManifests[aInstallLocation.name][aId]; try { - // Otherwise load the manifest from the add-on + // Otherwise the add-on has appeared in the install location. if (!newAddon) { + // Load the manifest from the add-on. let file = aInstallLocation.getLocationForID(aId); newAddon = loadManifestFromFile(file); + + // The default theme is never a foreign install + if (newAddon.type != "theme" || newAddon.internalName != XPIProvider.defaultSkin) + newAddon.foreignInstall = true; + } // The add-on in the manifest should match the add-on ID. if (newAddon.id != aId) @@ -2583,9 +2589,10 @@ var XPIProvider = { newAddon.installDate = aAddonState.mtime; newAddon.updateDate = aAddonState.mtime; - // Check if the add-on is in a scope where add-ons should install disabled + // Check if the add-on is a foreign install and is in a scope where + // add-ons that were dropped in should default to disabled. let disablingScopes = Prefs.getIntPref(PREF_EM_AUTO_DISABLED_SCOPES, 0); - if (aInstallLocation.scope & disablingScopes) + if (newAddon.foreignInstall && aInstallLocation.scope & disablingScopes) newAddon.userDisabled = true; // If there is migration data then apply it. @@ -2605,6 +2612,8 @@ var XPIProvider = { newAddon.sourceURI = aMigrateData.sourceURI; if ("releaseNotesURI" in aMigrateData) newAddon.releaseNotesURI = aMigrateData.releaseNotesURI; + if ("foreignInstall" in aMigrateData) + newAddon.foreignInstall = aMigrateData.foreignInstall; // Some properties should only be migrated if the add-on hasn't changed. // The version property isn't a perfect check for this but covers the @@ -3860,7 +3869,8 @@ const FIELDS_ADDON = "internal_id, id, location, version, type, internalName, " "iconURL, icon64URL, defaultLocale, visible, active, " + "userDisabled, appDisabled, pendingUninstall, descriptor, " + "installDate, updateDate, applyBackgroundUpdates, bootstrap, " + - "skinnable, size, sourceURI, releaseNotesURI, softDisabled"; + "skinnable, size, sourceURI, releaseNotesURI, softDisabled, " + + "foreignInstall"; /** * A helper function to log an SQL error. @@ -4005,7 +4015,8 @@ var XPIDatabase = { ":userDisabled, :appDisabled, :pendingUninstall, " + ":descriptor, :installDate, :updateDate, " + ":applyBackgroundUpdates, :bootstrap, :skinnable, " + - ":size, :sourceURI, :releaseNotesURI, :softDisabled)", + ":size, :sourceURI, :releaseNotesURI, :softDisabled, " + + ":foreignInstall)", addAddonMetadata_addon_locale: "INSERT INTO addon_locale VALUES " + "(:internal_id, :name, :locale)", addAddonMetadata_locale: "INSERT INTO locale (name, description, creator, " + @@ -4371,6 +4382,9 @@ var XPIDatabase = { // Build a list of sql statements that might recover useful data from this // and future versions of the schema var sql = []; + sql.push("SELECT internal_id, id, location, userDisabled, " + + "softDisabled, installDate, version, applyBackgroundUpdates, " + + "sourceURI, releaseNotesURI, foreignInstall FROM addon"); sql.push("SELECT internal_id, id, location, userDisabled, " + "softDisabled, installDate, version, applyBackgroundUpdates, " + "sourceURI, releaseNotesURI FROM addon"); @@ -4413,6 +4427,8 @@ var XPIDatabase = { migrateData[row.location][row.id].sourceURI = row.sourceURI; if ("releaseNotesURI" in row) migrateData[row.location][row.id].releaseNotesURI = row.releaseNotesURI; + if ("foreignInstall" in row) + migrateData[row.location][row.id].foreignInstall = row.foreignInstall; } var taStmt = this.connection.createStatement("SELECT id, minVersion, " + @@ -4533,6 +4549,7 @@ var XPIDatabase = { "bootstrap INTEGER, skinnable INTEGER, " + "size INTEGER, sourceURI TEXT, " + "releaseNotesURI TEXT, softDisabled INTEGER, " + + "foreignInstall INTEGER, " + "UNIQUE (id, location)"); this.connection.createTable("targetApplication", "addon_internal_id INTEGER, " + @@ -5207,6 +5224,7 @@ var XPIDatabase = { this.removeAddonMetadata(aOldAddon); aNewAddon.installDate = aOldAddon.installDate; aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates; + aNewAddon.foreignInstall = aOldAddon.foreignInstall; aNewAddon.active = (aNewAddon.visible && !aNewAddon.userDisabled && !aNewAddon.appDisabled) this.addAddonMetadata(aNewAddon, aDescriptor); @@ -6822,6 +6840,7 @@ AddonInternal.prototype = { softDisabled: false, sourceURI: null, releaseNotesURI: null, + foreignInstall: false, get selectedLocale() { if (this._selectedLocale) @@ -7094,7 +7113,7 @@ function AddonWrapper(aAddon) { ["id", "version", "type", "isCompatible", "isPlatformCompatible", "providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled", - "softDisabled", "skinnable", "size"].forEach(function(aProp) { + "softDisabled", "skinnable", "size", "foreignInstall"].forEach(function(aProp) { this.__defineGetter__(aProp, function() aAddon[aProp]); }, this); diff --git a/toolkit/mozapps/extensions/test/addons/test_migrate4_7/install.rdf b/toolkit/mozapps/extensions/test/addons/test_migrate4_7/install.rdf new file mode 100644 index 000000000000..072751cf2673 --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/test_migrate4_7/install.rdf @@ -0,0 +1,23 @@ + + + + + + addon7@tests.mozilla.org + 1.0 + + + Test 7 + Test Description + + + + xpcshell@tests.mozilla.org + 1 + 2 + + + + + diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_distribution.js b/toolkit/mozapps/extensions/test/xpcshell/test_distribution.js index 4f574629e5ad..13e809558a99 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_distribution.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_distribution.js @@ -89,6 +89,7 @@ function run_test_1() { do_check_eq(a1.version, "1.0"); do_check_true(a1.isActive); do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE); + do_check_false(a1.foreignInstall); run_test_2(); }); @@ -122,6 +123,7 @@ function run_test_3() { do_check_eq(a1.version, "2.0"); do_check_true(a1.isActive); do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE); + do_check_false(a1.foreignInstall); run_test_4(); }); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_install.js b/toolkit/mozapps/extensions/test/xpcshell/test_install.js index a31c89f1d153..36ee5797a84f 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_install.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_install.js @@ -163,6 +163,7 @@ function check_test_1() { do_check_true(do_get_addon("test_install1").exists()); do_check_in_crash_annotation(a1.id, a1.version); do_check_eq(a1.size, ADDON1_SIZE); + do_check_false(a1.foreignInstall); do_check_eq(a1.sourceURI.spec, Services.io.newFileURI(do_get_addon("test_install1")).spec); @@ -382,6 +383,7 @@ function check_test_5(install) { do_check_in_crash_annotation(a2.id, a2.version); do_check_eq(a2.sourceURI.spec, "http://localhost:4444/addons/test_install2_2.xpi"); + do_check_false(a2.foreignInstall); do_check_eq(a2.installDate.getTime(), gInstallDate); // Update date should be later (or the same if this test is too fast) diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js b/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js index f79f4f6190fe..39d4a7013e71 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js @@ -111,29 +111,31 @@ function prepare_profile() { a6.userDisabled = true; a6.findUpdates({ - onUpdateAvailable: function(aAddon, aInstall) { - completeAllInstalls([aInstall], function() { - restartManager(); + onUpdateAvailable: function(aAddon, aInstall6) { + AddonManager.getInstallForURL("http://localhost:4444/addons/test_migrate4_7.xpi", function(aInstall7) { + completeAllInstalls([aInstall6, aInstall7], function() { + restartManager(); - AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", - "addon2@tests.mozilla.org", - "addon3@tests.mozilla.org", - "addon4@tests.mozilla.org", - "addon5@tests.mozilla.org", - "addon6@tests.mozilla.org"], - function([a1, a2, a3, a4, a5, a6]) { - a3.userDisabled = true; - a4.userDisabled = false; + AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", + "addon2@tests.mozilla.org", + "addon3@tests.mozilla.org", + "addon4@tests.mozilla.org", + "addon5@tests.mozilla.org", + "addon6@tests.mozilla.org"], + function([a1, a2, a3, a4, a5, a6]) { + a3.userDisabled = true; + a4.userDisabled = false; - a5.findUpdates({ - onUpdateFinished: function() { - shutdownManager(); + a5.findUpdates({ + onUpdateFinished: function() { + shutdownManager(); - perform_migration(); - } - }, AddonManager.UPDATE_WHEN_USER_REQUESTED); + perform_migration(); + } + }, AddonManager.UPDATE_WHEN_USER_REQUESTED); + }); }); - }); + }, "application/x-xpinstall"); } }, AddonManager.UPDATE_WHEN_USER_REQUESTED); }); @@ -166,14 +168,16 @@ function test_results() { "addon3@tests.mozilla.org", "addon4@tests.mozilla.org", "addon5@tests.mozilla.org", - "addon6@tests.mozilla.org"], - function([a1, a2, a3, a4, a5, a6]) { + "addon6@tests.mozilla.org", + "addon7@tests.mozilla.org"], + function([a1, a2, a3, a4, a5, a6, a7]) { // addon1 was enabled do_check_neq(a1, null); do_check_false(a1.userDisabled); do_check_false(a1.appDisabled); do_check_true(a1.isActive); do_check_true(a1.applyBackgroundUpdates); + do_check_true(a1.foreignInstall); // addon2 was disabled do_check_neq(a2, null); @@ -181,6 +185,7 @@ function test_results() { do_check_false(a2.appDisabled); do_check_false(a2.isActive); do_check_false(a2.applyBackgroundUpdates); + do_check_true(a2.foreignInstall); // addon3 was pending-disable in the database do_check_neq(a3, null); @@ -188,6 +193,7 @@ function test_results() { do_check_false(a3.appDisabled); do_check_false(a3.isActive); do_check_true(a3.applyBackgroundUpdates); + do_check_true(a3.foreignInstall); // addon4 was pending-enable in the database do_check_neq(a4, null); @@ -195,6 +201,7 @@ function test_results() { do_check_false(a4.appDisabled); do_check_true(a4.isActive); do_check_true(a4.applyBackgroundUpdates); + do_check_true(a4.foreignInstall); // addon5 was enabled in the database but needed a compatibiltiy update do_check_neq(a5, null); @@ -202,6 +209,7 @@ function test_results() { do_check_false(a5.appDisabled); do_check_true(a5.isActive); do_check_true(a5.applyBackgroundUpdates); + do_check_true(a5.foreignInstall); // addon6 was disabled and compatible but a new version has been installed do_check_neq(a6, null); @@ -210,8 +218,20 @@ function test_results() { do_check_false(a6.appDisabled); do_check_false(a6.isActive); do_check_true(a6.applyBackgroundUpdates); + do_check_true(a6.foreignInstall); do_check_eq(a6.sourceURI.spec, "http://localhost:4444/addons/test_migrate4_6.xpi"); do_check_eq(a6.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml"); + + // addon7 was installed manually + do_check_neq(a7, null); + do_check_eq(a7.version, "1.0"); + do_check_false(a7.userDisabled); + do_check_false(a7.appDisabled); + do_check_true(a7.isActive); + do_check_true(a7.applyBackgroundUpdates); + do_check_false(a7.foreignInstall); + do_check_eq(a7.sourceURI.spec, "http://localhost:4444/addons/test_migrate4_7.xpi"); + do_check_eq(a7.releaseNotesURI, null); testserver.stop(do_test_finished); }); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_startup.js b/toolkit/mozapps/extensions/test/xpcshell/test_startup.js index 856362b90e90..71f41b6775f8 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_startup.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_startup.js @@ -202,6 +202,7 @@ function run_test_1() { do_check_in_crash_annotation(addon1.id, addon1.version); do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE); do_check_eq(a1.sourceURI, null); + do_check_true(a1.foreignInstall); do_check_neq(a2, null); do_check_eq(a2.id, "addon2@tests.mozilla.org"); @@ -213,6 +214,7 @@ function run_test_1() { do_check_in_crash_annotation(addon2.id, addon2.version); do_check_eq(a2.scope, AddonManager.SCOPE_PROFILE); do_check_eq(a2.sourceURI, null); + do_check_true(a2.foreignInstall); do_check_neq(a3, null); do_check_eq(a3.id, "addon3@tests.mozilla.org"); @@ -224,6 +226,7 @@ function run_test_1() { do_check_in_crash_annotation(addon3.id, addon3.version); do_check_eq(a3.scope, AddonManager.SCOPE_PROFILE); do_check_eq(a3.sourceURI, null); + do_check_true(a3.foreignInstall); do_check_eq(a4, null); do_check_false(isExtensionInAddonsList(profileDir, "addon4@tests.mozilla.org")); @@ -297,6 +300,7 @@ function run_test_2() { do_check_true(hasFlag(a1.permissions, AddonManager.PERM_CAN_UPGRADE)); do_check_in_crash_annotation(addon1.id, a1.version); do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE); + do_check_true(a1.foreignInstall); do_check_neq(a2, null); do_check_eq(a2.id, "addon2@tests.mozilla.org"); @@ -308,6 +312,7 @@ function run_test_2() { do_check_true(hasFlag(a2.permissions, AddonManager.PERM_CAN_UPGRADE)); do_check_in_crash_annotation(addon2.id, a2.version); do_check_eq(a2.scope, AddonManager.SCOPE_PROFILE); + do_check_true(a2.foreignInstall); do_check_eq(a3, null); do_check_false(isExtensionInAddonsList(profileDir, "addon3@tests.mozilla.org")); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_theme.js b/toolkit/mozapps/extensions/test/xpcshell/test_theme.js index 5cb3bb049dd4..971f410159f5 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_theme.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_theme.js @@ -94,12 +94,14 @@ function run_test() { function([d, t1, t2]) { do_check_neq(d, null); do_check_false(d.skinnable); + do_check_false(d.foreignInstall); do_check_neq(t1, null); do_check_false(t1.userDisabled); do_check_false(t1.appDisabled); do_check_true(t1.isActive); do_check_true(t1.skinnable); + do_check_true(t1.foreignInstall); do_check_eq(t1.screenshots, null); do_check_true(isThemeInAddonsList(profileDir, t1.id)); do_check_false(hasFlag(t1.permissions, AddonManager.PERM_CAN_DISABLE)); @@ -112,6 +114,7 @@ function run_test() { do_check_false(t2.appDisabled); do_check_false(t2.isActive); do_check_false(t2.skinnable); + do_check_true(t2.foreignInstall); do_check_eq(t2.screenshots, null); do_check_false(isThemeInAddonsList(profileDir, t2.id)); do_check_false(hasFlag(t2.permissions, AddonManager.PERM_CAN_DISABLE)); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update.js b/toolkit/mozapps/extensions/test/xpcshell/test_update.js index afdfdae75e1c..f39908e06b2a 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update.js @@ -90,6 +90,7 @@ function run_test_1() { do_check_eq(a1.version, "1.0"); do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT); do_check_eq(a1.releaseNotesURI, null); + do_check_true(a1.foreignInstall); a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT; @@ -219,6 +220,7 @@ function check_test_2() { do_check_true(isExtensionInAddonsList(profileDir, a1.id)); do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE); do_check_eq(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml"); + do_check_true(a1.foreignInstall); a1.uninstall(); restartManager();