Bug 537180 - Fennec uses old blocklisting URL [r=mfinkle]
--- a/app/mobile.js
+++ b/app/mobile.js
@@ -181,17 +181,17 @@ pref("extensions.getAddons.recommended.b
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/list/featured/all/10/%OS%/%VERSION%");
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/mobile/search?q=%TERMS%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/mobile/api/%API_VERSION%/search/%TERMS%/all/10/%OS%/%VERSION%");
pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/mobile/");
/* blocklist preferences */
pref("extensions.blocklist.enabled", true);
pref("extensions.blocklist.interval", 86400);
-pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/2/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
+pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
/* block popups by default, and notify the user about blocked popups */
pref("dom.disable_open_during_load", true);
pref("privacy.popups.showBrowserMessage", true);
pref("keyword.enabled", true);
pref("keyword.URL", "http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=");
--- a/chrome/content/bindings/extensions.xml
+++ b/chrome/content/bindings/extensions.xml
@@ -21,17 +21,18 @@
<xul:label class="title" xbl:inherits="value=name" crop="end" flex="1"/>
<xul:label class="normal" xbl:inherits="value=version"/>
<xul:spacer flex="1000"/>
<xul:label class="normal" xbl:inherits="value=typeLabel"/>
</xul:hbox>
<xul:vbox>
<xul:label class="normal hide-on-select" xbl:inherits="value=description" crop="end" flex="1"/>
<xul:description class="normal show-on-select" xbl:inherits="xbl:text=description" flex="1"/>
- <xul:label class="normal-bold" xbl:inherits="value=updateStatus"/>
+ <xul:label class="updateStatus normal-bold" xbl:inherits="value=updateStatus"/>
+ <xul:label class="blockStatus normal-bold" xbl:inherits="value=blockedStatus"/>
</xul:vbox>
</xul:vbox>
</xul:hbox>
<xul:hbox class="show-on-select buttons-box">
<xul:button anonid="options-button" type="checkbox" class="addon-options" label="&addonOptions.label;"
oncommand="document.getBindingParent(this).toggleOptions();"/>
<xul:spacer flex="1"/>
<xul:button anonid="enable-button" class="show-on-disable hide-on-enable hide-on-uninstall addon-enable" label="&addonEnable.label;"
--- a/chrome/content/extensions.js
+++ b/chrome/content/extensions.js
@@ -275,46 +275,60 @@ var ExtensionsView = {
this.hideOptions();
},
getAddonsFromLocal: function ev_getAddonsFromLocal() {
this.clearSection("local");
let self = this;
AddonManager.getAddonsByTypes(["extension", "theme", "locale"], function(items) {
+ let strings = Elements.browserBundle;
let anyUpdateable = false;
for (let i = 0; i < items.length; i++) {
let addon = items[i];
let appManaged = (addon.scope == AddonManager.SCOPE_APPLICATION);
let opType = self._getOpTypeForOperations(addon.pendingOperations);
let updateable = (addon.permissions & AddonManager.PERM_CAN_UPGRADE) > 0;
let uninstallable = (addon.permissions & AddonManager.PERM_CAN_UNINSTALL) > 0;
+ let blocked = "";
+ switch(addon.blocklistState) {
+ case Ci.nsIBlocklistService.STATE_BLOCKED:
+ blocked = strings.getString("addonBlocked.blocked")
+ break;
+ case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
+ blocked = strings.getString("addonBlocked.softBlocked");
+ break;
+ case Ci.nsIBlocklistService.STATE_OUTDATED:
+ blocked = srings.getString("addonBlocked.outdated");
+ break;
+ }
+
if (updateable)
anyUpdateable = true;
let listitem = self._createItem(addon, "local");
listitem.setAttribute("isDisabled", !addon.isActive);
listitem.setAttribute("appDisabled", addon.appDisabled);
listitem.setAttribute("appManaged", appManaged);
listitem.setAttribute("description", addon.description);
listitem.setAttribute("optionsURL", addon.optionsURL);
listitem.setAttribute("opType", opType);
listitem.setAttribute("updateable", updateable);
listitem.setAttribute("isReadonly", !uninstallable);
+ listitem.setAttribute("blockedStatus", blocked);
listitem.addon = addon;
self._list.insertBefore(listitem, self._repoItem);
}
// Load the search engines
let defaults = Services.search.getDefaultEngines({ }).map(function (e) e.name);
function isDefault(aEngine)
defaults.indexOf(aEngine.name) != -1
- let strings = Elements.browserBundle;
let defaultDescription = strings.getString("addonsSearchEngine.description");
let engines = Services.search.getEngines({ });
for (let e = 0; e < engines.length; e++) {
let engine = engines[e];
let addon = {};
addon.id = engine.name;
addon.type = "search";
@@ -697,22 +711,23 @@ var AddonSearchResults = {
///////////////////////////////////////////////////////////////////////////////
// XPInstall download helper
function AddonInstallListener() {
}
AddonInstallListener.prototype = {
_updating: false,
+
onInstallEnded: function(aInstall, aAddon) {
// XXX fix updating stuff
if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL)
ExtensionsView.showRestart(this._updating ? "update" : "normal");
- this._showAlert(true);
+ this._showInstallCompleteAlert(true);
if (!ExtensionsView.visible)
return;
let element = ExtensionsView.getElementForAddon(aInstall.sourceURI.spec);
if (!element)
return;
@@ -726,17 +741,17 @@ AddonInstallListener.prototype = {
element.removeAttribute("updating");
// Remember that we are updating so we can customize the restart message
this._updating = true;
}
},
onInstallFailed: function(aInstall, aError) {
- this._showAlert(false);
+ this._showInstallCompleteAlert(false);
if (ExtensionsView.visible) {
let element = ExtensionsView.getElementForAddon(aInstall.sourceURI.spec);
if (!element)
return;
element.removeAttribute("opType");
let strings = Services.strings.createBundle("chrome://global/locale/xpinstall/xpinstall.properties");
@@ -775,28 +790,59 @@ AddonInstallListener.prototype = {
let progress = Math.round((aInstall.progress / aInstall.maxProgress) * 100);
element.setAttribute("progress", progress);
},
onDownloadFailed: function(aInstall, aError) {
this.onInstallFailed(aInstall, aError);
},
- _showAlert: function xpidm_showAlert(aSucceeded) {
+ onDownloadCancelled: function(aInstall, aAddon) {
+ let strings = Elements.browserBundle;
+ let brandBundle = document.getElementById("bundle_brand");
+ let brandShortName = brandBundle.getString("brandShortName");
+ let host = (aInstall.originatingURI instanceof Ci.nsIStandardURL) && aInstall.originatingURI.host;
+ if (!host)
+ host = (aInstall.sourceURI instanceof Ci.nsIStandardURL) && aInstall.sourceURI.host;
+
+ let error = (host || aInstall.error == 0) ? "addonError" : "addonLocalError";
+ if (aInstall.error != 0)
+ error += aInstall.error;
+ else if (aInstall.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
+ error += "Blocklisted";
+ else
+ error += "Incompatible";
+
+ let messageString = strings.getString(error);
+ messageString = messageString.replace("#1", aInstall.name);
+ if (host)
+ messageString = messageString.replace("#2", host);
+ messageString = messageString.replace("#3", brandShortName);
+ messageString = messageString.replace("#4", Services.appinfo.version);
+
+ this._showAlert(messageString);
+ },
+
+ _showInstallCompleteAlert: function xpidm_showAlert(aSucceeded) {
+ let strings = Elements.browserBundle;
+ let msg = aSucceeded ? strings.getString("alertAddonsInstalled") :
+ strings.getString("alertAddonsFail");
+ this._showAlert(msg);
+ },
+
+ _showAlert: function xpidm_showAlert(aMessage) {
if (ExtensionsView.visible)
return;
let strings = Elements.browserBundle;
- let message = aSucceeded ? strings.getString("alertAddonsInstalled") :
- strings.getString("alertAddonsFail");
let observer = {
observe: function (aSubject, aTopic, aData) {
if (aTopic == "alertclickcallback")
BrowserUI.showPanel("addons-container");
}
};
let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, strings.getString("alertAddons"),
- message, true, "", observer, "addons");
+ aMessage, true, "", observer, "addons");
}
};
new file mode 100644
--- /dev/null
+++ b/components/BlocklistPrompt.js
@@ -0,0 +1,93 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Alerts Service.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wes Johnston <wjohnston@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cc = Components.classes;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+// -----------------------------------------------------------------------
+// BlocklistPrompt Service
+// -----------------------------------------------------------------------
+
+
+function BlocklistPrompt() { }
+
+BlocklistPrompt.prototype = {
+ prompt: function(aAddons, aCount) {
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+ if (win.ExtensionsView.visible) {
+ win.ExtensionsView.showRestart("blocked");
+ } else {
+ let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+ let notifyBox = win.getNotificationBox();
+ let restartCallback = function(aNotification, aDescription) {
+ // Notify all windows that an application quit has been requested
+ var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
+ Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
+
+ // If nothing aborted, quit the app
+ if (cancelQuit.data == false) {
+ let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
+ appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
+ }
+ };
+
+ let buttons = [{accessKey: null,
+ label: bundle.GetStringFromName("notificationRestart.button"),
+ callback: restartCallback}];
+ notifyBox.appendNotification(bundle.GetStringFromName("notificationRestart.blocked"),
+ "blocked-add-on",
+ "",
+ "PRIORITY_CRITICAL_HIGH",
+ buttons);
+ }
+ // Disable softblocked items automatically
+ for (let i = 0; i < aAddons.length; i++) {
+ if (aAddons[i].item instanceof Ci.nsIPluginTag)
+ addonList[i].item.disabled = true;
+ else
+ aAddons[i].item.userDisabled = true;
+ }
+ },
+ classID: Components.ID("{4e6ea350-b09a-11df-94e2-0800200c9a66}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistPrompt])
+};
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([BlocklistPrompt]);
+
--- a/components/Makefile.in
+++ b/components/Makefile.in
@@ -66,16 +66,17 @@ EXTRA_COMPONENTS = \
HelperAppDialog.js \
PromptService.js \
BrowserCLH.js \
ContentDispatchChooser.js \
AutoCompleteCache.js \
AddonUpdateService.js \
FormAutoComplete.js \
LoginManager.js \
+ BlocklistPrompt.js \
$(NULL)
ifndef ANDROID
EXTRA_COMPONENTS += AlertsService.js
endif
ifneq (Android,$(OS_TARGET))
DIRS = phone \
--- a/components/MobileComponents.manifest
+++ b/components/MobileComponents.manifest
@@ -85,8 +85,12 @@ category update-timer AddonUpdateService
# FormAutoComplete.js
component {cccd414c-3ec2-4cc5-9dc4-36c87cc3c4fe} FormAutoComplete.js
contract @mozilla.org/satchel/form-autocomplete;1 {cccd414c-3ec2-4cc5-9dc4-36c87cc3c4fe}
# LoginManager.js
component {f9a0edde-2a8d-4bfd-a08c-3f9333213a85} LoginManager.js
contract @mozilla.org/login-manager;1 {f9a0edde-2a8d-4bfd-a08c-3f9333213a85}
+
+# BlocklistPrompt.js
+component {4e6ea350-b09a-11df-94e2-0800200c9a66} BlocklistPrompt.js
+contract @mozilla.org/addons/blocklist-prompt;1 {4e6ea350-b09a-11df-94e2-0800200c9a66}
--- a/locales/en-US/chrome/browser.properties
+++ b/locales/en-US/chrome/browser.properties
@@ -35,16 +35,36 @@ addonUpdate.checking=Checking for updates…
addonUpdate.updating=Updating to %S
addonUpdate.updated=Updated to %S
addonUpdate.compatibility=A compatibility update has been applied
addonUpdate.noupdate=No updates were found
addonUpdate.notsupported=Updates not supported
addonUpdate.disabled=Updates are disabled
addonUpdate.error=An error occurred
+addonBlocked.blocked=Blocked
+addonBlocked.softBlocked=Known to cause security or stability issues
+addonBlocked.outdated=Out of date
+
+# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4):
+# #1 is the add-on name, #2 is the add-on host, #3 is the application name
+addonError-1=The add-on could not be downloaded because of a connection failure on #2.
+addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
+addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
+addonError-4=#1 could not be installed because #3 cannot modify the needed file.
+
+# LOCALIZATION NOTE (addonLocalError-1, addonLocalError-2, addonLocalError-3, addonLocalError-4, addonErrorIncompatible, addonErrorBlocklisted):
+# #1 is the add-on name, #3 is the application name, #4 is the application version
+addonLocalError-1=This add-on could not be installed because of a filesystem error.
+addonLocalError-2=This add-on could not be installed because it does not match the add-on #3 expected.
+addonLocalError-3=This add-on could not be installed because it appears to be corrupt.
+addonLocalError-4=#1 could not be installed because #3 cannot modify the needed file.
+addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
+addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
+
# Download Manager
# LOCALIZATION NOTE (Status): — is the "em dash" (long dash)
# #1 download size for FINISHED or download state; #2 host (e.g., eTLD + 1, IP)
downloadsStatus=#1 — #2
downloadsUnknownSize=Unknown size
# LOCALIZATION NOTE (KnownSize): #1 size number; #2 size unit
downloadsKnownSize=#1 #2
donwloadsYesterday=Yesterday
@@ -68,16 +88,17 @@ alertAddonsDisabled=#1 incompatible add-
alertDownloads=Downloads
alertDownloadsStart=Downloading: %S
alertDownloadsDone=%S has finished downloading
# Notifications
notificationRestart.normal=Restart to complete changes.
notificationRestart.update=Add-ons updated. Restart to complete changes.
+notificationRestart.blocked=Unsafe add-ons installed. Restart to disable.
notificationRestart.button=Restart
# Popup Blocker
popupWarning=%S prevented this site from opening a pop-up window.
popupWarningMultiple=%S prevented this site from opening %S pop-up windows.
popupButtonAllowOnce=Show
popupButtonAlwaysAllow2=Always Show
popupButtonNeverWarn2=Never Show