Bug 1151509 - Implement the front-end side of the warning about add-ons detected as no longer signed during the periodic check. r=dtownsend

This commit is contained in:
Dão Gottwald 2015-05-08 19:27:25 +02:00
parent 28efac3e81
commit 3c7efedaab
9 changed files with 192 additions and 15 deletions

View File

@ -48,6 +48,7 @@ pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCAL
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%?src=firefox");
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%");
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/list/recommended/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
pref("extensions.getAddons.link.url", "https://addons.mozilla.org/%LOCALE%/firefox/");
// Blocklist preferences
pref("extensions.blocklist.enabled", true);
@ -71,6 +72,7 @@ pref("extensions.autoDisableScopes", 15);
// Don't require signed add-ons by default
pref("xpinstall.signatures.required", false);
pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing");
// Dictionary download preference
pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/");

View File

@ -505,6 +505,10 @@ BrowserGlue.prototype = {
case "flash-plugin-hang":
this._handleFlashHang();
break;
case "xpi-signature-changed":
if (JSON.parse(data).disabled.length)
this._notifyUnsignedAddonsDisabled();
break;
}
},
@ -553,6 +557,7 @@ BrowserGlue.prototype = {
os.addObserver(this, "browser-search-service", false);
os.addObserver(this, "restart-in-safe-mode", false);
os.addObserver(this, "flash-plugin-hang", false);
os.addObserver(this, "xpi-signature-changed", false);
this._flashHangCount = 0;
},
@ -600,6 +605,7 @@ BrowserGlue.prototype = {
Services.prefs.removeObserver(POLARIS_ENABLED, this);
#endif
os.removeObserver(this, "flash-plugin-hang");
os.removeObserver(this, "xpi-signature-changed");
},
_onAppDefaults: function BG__onAppDefaults() {
@ -897,6 +903,27 @@ BrowserGlue.prototype = {
nb.PRIORITY_INFO_LOW, buttons);
},
_notifyUnsignedAddonsDisabled: function () {
let win = this.getMostRecentBrowserWindow();
if (!win)
return;
let message = win.gNavigatorBundle.getString("unsignedAddonsDisabled.message");
let buttons = [
{
label: win.gNavigatorBundle.getString("unsignedAddonsDisabled.learnMore.label"),
accessKey: win.gNavigatorBundle.getString("unsignedAddonsDisabled.learnMore.accesskey"),
callback: function () {
win.BrowserOpenAddonsMgr("addons://list/extension?unsigned=true");
}
},
];
let nb = win.document.getElementById("high-priority-global-notificationbox");
nb.appendNotification(message, "unsigned-addons-disabled", "",
nb.PRIORITY_WARNING_MEDIUM, buttons);
},
_firstWindowTelemetry: function(aWindow) {
#ifdef XP_WIN
let SCALING_PROBE_NAME = "DISPLAY_SCALING_MSWIN";

View File

@ -96,6 +96,10 @@ addonLocalError-5=This add-on could not be installed because it has not been ver
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.
unsignedAddonsDisabled.message=One or more installed add-ons cannot be verified and have been disabled.
unsignedAddonsDisabled.learnMore.label=Learn More
unsignedAddonsDisabled.learnMore.accesskey=L
# LOCALIZATION NOTE (deveditionTheme.name): This should be nearly the brand name for aurora.
# See browser/branding/aurora/locales/*/brand.properties
deveditionTheme.name=Developer Edition

View File

@ -23,6 +23,9 @@
<!ENTITY cmd.back.tooltip "Go back one page">
<!ENTITY cmd.forward.tooltip "Go forward one page">
<!ENTITY showUnsignedExtensions.button.label "Some extensions could not be verified">
<!ENTITY showAllExtensions.button.label "Show all extensions">
<!-- global warnings -->
<!ENTITY warning.safemode.label "All add-ons have been disabled by safe mode.">
<!ENTITY warning.checkcompatibility.label "Add-on compatibility checking is disabled. You may have incompatible add-ons.">
@ -232,3 +235,18 @@
<!ENTITY experiment.info.changetelemetry.accesskey "T">
<!ENTITY setting.learnmore "Learn More…">
<!ENTITY disabledUnsigned.heading "Some add-ons have been disabled">
<!-- LOCALIZATION NOTE (disabledUnsigned.description.start, disabledUnsigned.description.findAddonsLink, disabledUnsigned.description.end):
These entities form a sentence, with
disabledUnsigned.description.findAddonsLink being a link to an external site. -->
<!ENTITY disabledUnsigned.description.start "The following add-ons have not been verified for use in &brandShortName;. You can ">
<!ENTITY disabledUnsigned.description.findAddonsLink "find replacements">
<!ENTITY disabledUnsigned.description.end " or ask the developer to get them verified.">
<!ENTITY disabledUnsigned.learnMore "Learn more about our efforts to help keep you safe online.">
<!-- LOCALIZATION NOTE (disabledUnsigned.devInfo.start, disabledUnsigned.devInfo.linkToManual, disabledUnsigned.devInfo.end):
These entities form a sentence, with disabledUnsigned.devInfo.linkToManual
being a link to an external site. -->
<!ENTITY disabledUnsigned.devInfo.start "Developers interested in getting their add-ons verified can continue by reading our ">
<!ENTITY disabledUnsigned.devInfo.linkToManual "manual">
<!ENTITY disabledUnsigned.devInfo.end ".">

View File

@ -1333,6 +1333,24 @@ var gViewController = {
mainWindow.openAdvancedPreferences("dataChoicesTab");
},
},
cmd_showUnsignedExtensions: {
isEnabled: function cmd_showUnsignedExtensions_isEnabled() {
return true;
},
doCommand: function cmd_showUnsignedExtensions_doCommand() {
gViewController.loadView("addons://list/extension?unsigned=true");
},
},
cmd_showAllExtensions: {
isEnabled: function cmd_showUnsignedExtensions_isEnabled() {
return true;
},
doCommand: function cmd_showUnsignedExtensions_doCommand() {
gViewController.loadView("addons://list/extension");
},
},
},
supportsCommand: function gVC_supportsCommand(aCommand) {
@ -1834,6 +1852,7 @@ var gCategories = {
aId = aPreviousView;
view = gViewController.parseViewId(aPreviousView);
}
aId = aId.replace(/\?.*/, "");
Services.prefs.setCharPref(PREF_UI_LASTCATEGORY, aId);
@ -2589,9 +2608,33 @@ var gListView = {
item.showInDetailView();
}
}, false);
document.getElementById("signing-learn-more").setAttribute("href",
Services.urlFormatter.formatURLPref("app.support.baseURL") + "unsigned-addons");
let findSignedAddonsLink = document.getElementById("find-alternative-addons");
try {
findSignedAddonsLink.setAttribute("href",
Services.urlFormatter.formatURLPref("extensions.getAddons.link.url"));
} catch (e) {
findSignedAddonsLink.classList.remove("text-link");
}
try {
document.getElementById("signing-dev-manual-link").setAttribute("href",
Services.prefs.getCharPref("xpinstall.signatures.devInfoURL"));
} catch (e) {
document.getElementById("signing-dev-info").hidden = true;
}
},
show: function gListView_show(aType, aRequest) {
let showOnlyDisabledUnsigned = false;
if (aType.endsWith("?unsigned=true")) {
aType = aType.replace(/\?.*/, "");
showOnlyDisabledUnsigned = true;
}
if (!(aType in AddonManager.addonTypes))
throw Components.Exception("Attempting to show unknown type " + aType, Cr.NS_ERROR_INVALID_ARG);
@ -2606,8 +2649,7 @@ var gListView = {
navigator.plugins.refresh(false);
}
var self = this;
getAddonsAndInstalls(aType, function show_getAddonsAndInstalls(aAddonsList, aInstallsList) {
getAddonsAndInstalls(aType, (aAddonsList, aInstallsList) => {
if (gViewController && aRequest != gViewController.currentViewRequest)
return;
@ -2619,14 +2661,16 @@ var gListView = {
for (let installItem of aInstallsList)
elements.push(createItem(installItem, true));
self.showEmptyNotice(elements.length == 0);
this.showEmptyNotice(elements.length == 0);
if (elements.length > 0) {
sortElements(elements, ["uiState", "name"], true);
for (let element of elements)
self._listBox.appendChild(element);
this._listBox.appendChild(element);
}
gEventManager.registerInstallListener(self);
this.filterDisabledUnsigned(showOnlyDisabledUnsigned);
gEventManager.registerInstallListener(this);
gViewController.updateCommands();
gViewController.notifyViewChanged();
});
@ -2637,6 +2681,25 @@ var gListView = {
doPendingUninstalls(this._listBox);
},
filterDisabledUnsigned: function gListView_filterDisabledUnsigned(aFilter = true) {
let foundDisabledUnsigned = false;
for (let item of this._listBox.childNodes) {
let isDisabledUnsigned = item.mAddon.appDisabled &&
item.mAddon.signedState <= AddonManager.SIGNEDSTATE_MISSING;
if (isDisabledUnsigned)
foundDisabledUnsigned = true;
else
item.hidden = aFilter;
}
document.getElementById("show-disabled-unsigned-extensions").hidden =
aFilter || !foundDisabledUnsigned;
document.getElementById("show-all-extensions").hidden = !aFilter;
document.getElementById("disabled-unsigned-addons-info").hidden = !aFilter;
},
showEmptyNotice: function gListView_showEmptyNotice(aShow) {
this._emptyNotice.hidden = !aShow;
this._listBox.hidden = aShow;

View File

@ -92,6 +92,8 @@
<command id="cmd_resetAddonAutoUpdate"/>
<command id="cmd_experimentsLearnMore"/>
<command id="cmd_experimentsOpenTelemetryPreferences"/>
<command id="cmd_showUnsignedExtensions"/>
<command id="cmd_showAllExtensions"/>
</commandset>
<!-- view commands - these act on the selected addon -->
@ -159,9 +161,12 @@
tooltiptext="&view.recentUpdates.label;" disabled="true"/>
</richlistbox>
</vbox>
<vbox flex="1">
<vbox class="main-content" flex="1">
<!-- main header -->
<hbox id="header" align="center">
<button id="show-all-extensions" hidden="true"
label="&showAllExtensions.button.label;"
command="cmd_showAllExtensions"/>
<spacer flex="1"/>
<hbox id="updates-container" align="center">
<image class="spinner"/>
@ -180,6 +185,9 @@
label="&updates.restart.label;"
command="cmd_restartApp"/>
</hbox>
<button id="show-disabled-unsigned-extensions" hidden="true"
label="&showUnsignedExtensions.button.label;"
command="cmd_showUnsignedExtensions"/>
<toolbarbutton id="header-utils-btn" class="header-button" type="menu"
tooltiptext="&toolsMenu.tooltip;">
<menupopup id="utils-menu">
@ -216,7 +224,6 @@
searchbuttonlabel="&search.buttonlabel;"
placeholder="&search.placeholder;"/>
</hbox>
<box id="view-port-container" class="main-content" flex="1">
<!-- view port -->
<deck id="view-port" flex="1" selectedIndex="0">
@ -329,6 +336,17 @@
<!-- list view -->
<vbox id="list-view" flex="1" class="view-pane" align="stretch" tabindex="0">
<!-- info UI for add-ons that have been disabled for being unsigned -->
<vbox id="disabled-unsigned-addons-info" hidden="true">
<label id="disabled-unsigned-addons-heading" value="&disabledUnsigned.heading;"/>
<description>
&disabledUnsigned.description.start;<label class="text-link plain" id="find-alternative-addons">&disabledUnsigned.description.findAddonsLink;</label>&disabledUnsigned.description.end;
</description>
<hbox pack="start"><label class="text-link" id="signing-learn-more">&disabledUnsigned.learnMore;</label></hbox>
<description id="signing-dev-info">
&disabledUnsigned.devInfo.start;<label class="text-link plain" id="signing-dev-manual-link">&disabledUnsigned.devInfo.linkToManual;</label>&disabledUnsigned.devInfo.end;
</description>
</vbox>
<hbox class="view-header global-warning-container">
<!-- global warnings -->
<hbox class="global-warning" flex="1">
@ -690,7 +708,6 @@
</hbox>
</scrollbox>
</deck>
</box>
</vbox>
</hbox>
</page>

View File

@ -128,7 +128,8 @@ function get_test_items() {
var item = gManagerWindow.document.getElementById("addon-list").firstChild;
while (item) {
if (item.mAddon.id.substring(item.mAddon.id.length - tests.length) == tests)
if (item.mAddon.id.substring(item.mAddon.id.length - tests.length) == tests &&
!is_hidden(item))
items[item.mAddon.name] = item;
item = item.nextSibling;
}
@ -435,7 +436,35 @@ add_test(function() {
is(get_node(addon, "error-link").href, Services.prefs.getCharPref("xpinstall.signatures.infoURL"), "Error link should be correct");
is_element_hidden(get_node(addon, "pending"), "Pending message should be hidden");
run_next_test();
info("Filter for disabled unsigned extensions");
let filterButton = gManagerWindow.document.getElementById("show-disabled-unsigned-extensions");
let showAllButton = gManagerWindow.document.getElementById("show-all-extensions");
let signingInfoUI = gManagerWindow.document.getElementById("disabled-unsigned-addons-info");
is_element_visible(filterButton, "Button for showing disabled unsigned extensions should be visible");
is_element_hidden(showAllButton, "Button for showing all extensions should be hidden");
is_element_hidden(signingInfoUI, "Signing info UI should be hidden");
filterButton.click();
wait_for_view_load(gManagerWindow, () => {
is_element_hidden(filterButton, "Button for showing disabled unsigned extensions should be hidden");
is_element_visible(showAllButton, "Button for showing all extensions should be visible");
is_element_visible(signingInfoUI, "Signing info UI should be visible");
items = get_test_items();
is(Object.keys(items).length, 1, "Only one add-on should be shown");
is(Object.keys(items)[0], "Test add-on 11", "The disabled unsigned extension should be shown");
showAllButton.click();
wait_for_view_load(gManagerWindow, () => {
items = get_test_items();
is(Object.keys(items).length, 11, "All add-ons should be shown again");
is_element_visible(filterButton, "Button for showing disabled unsigned extensions should be visible again");
is_element_hidden(showAllButton, "Button for showing all extensions should be hidden again");
is_element_hidden(signingInfoUI, "Signing info UI should be hidden again");
run_next_test();
});
});
});
});

View File

@ -1017,3 +1017,23 @@ button.button-link:not([disabled="true"]):active:hover {
#detail-view[active="true"] #detail-experiment-bullet {
fill: rgb(106, 201, 20);
}
/*** info UI for add-ons that have been disabled for being unsigned ***/
#show-disabled-unsigned-extensions:not(:hover) {
background-color: #fcf8ed;
}
#disabled-unsigned-addons-info {
margin-bottom: 2em;
}
#disabled-unsigned-addons-heading {
font-size: 1.4em;
font-weight: bold;
margin-bottom: .5em;
}
#signing-dev-info {
font-style: italic;
}

View File

@ -48,10 +48,6 @@ xul|caption > xul|label {
margin: 0 !important;
}
xul|description {
-moz-margin-start: 0;
}
*|*.main-content {
padding-top: 40px;
-moz-padding-end: 44px; /* compensate the 4px margin of child elements */
@ -75,7 +71,8 @@ xul|groupbox {
font-size: 1.25rem;
}
xul|groupbox xul|label {
xul|groupbox xul|label,
xul|groupbox xul|description {
/* !important needed to override toolkit !important rule */
-moz-margin-start: 0 !important;
-moz-margin-end: 0 !important;