author | Dave Townsend <dtownsend@oxymoronical.com> |
Thu, 29 Apr 2010 13:11:23 -0700 | |
changeset 41552 | d2a2b786fcc9ce88ed1fa451099b5bcaf5ada1d7 |
parent 41551 | 7ebf7aac89740876d859bfa1fbcc112fd7f1dd30 |
child 41553 | d56ea9503e6872c3b10a3f2c69e7e694c2927c01 |
push id | 1 |
push user | root |
push date | Tue, 26 Apr 2011 22:38:44 +0000 |
treeherder | mozilla-beta@bfdb6e623a36 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | robstrong, dveditz |
bugs | 553169 |
milestone | 1.9.3a5pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
|
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -47,21 +47,16 @@ #define UNIX_BUT_NOT_MAC #endif #endif pref("general.startup.browser", true); pref("browser.chromeURL","chrome://browser/content/"); pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul"); -pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul"); -pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul"); -pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul"); -pref("xpinstall.dialog.progress.type.skin", "Extension:Manager"); -pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager"); // Developers can set this to |true| if they are constantly changing files in their // extensions directory so that the extension system does not constantly think that // their extensions are being updated and thus reregistered every time the app is // started. pref("extensions.ignoreMTimeChanges", false); // Enables some extra Extension System Logging (can reduce performance) pref("extensions.logging.enabled", false);
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -592,28 +592,34 @@ const gXPInstallObserver = { } return null; }, observe: function (aSubject, aTopic, aData) { var brandBundle = document.getElementById("bundle_brand"); switch (aTopic) { - case "xpinstall-install-blocked": - var installInfo = aSubject.QueryInterface(Components.interfaces.nsIXPIInstallInfo); + case "addon-install-blocked": + var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo); var win = installInfo.originatingWindow; var shell = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell); var browser = this._getBrowser(shell); if (browser) { var host = installInfo.originatingURI.host; var brandShortName = brandBundle.getString("brandShortName"); var notificationName, messageString, buttons; - if (!gPrefService.getBoolPref("xpinstall.enabled")) { + var enabled = true; + try { + enabled = gPrefService.getBoolPref("xpinstall.enabled"); + } + catch (e) { + } + if (!enabled) { notificationName = "xpinstall-disabled" if (gPrefService.prefIsLocked("xpinstall.enabled")) { messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked"); buttons = []; } else { messageString = gNavigatorBundle.getFormattedString("xpinstallDisabledMessage", [brandShortName, host]); @@ -634,19 +640,17 @@ const gXPInstallObserver = { messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning", [brandShortName, host]); buttons = [{ label: gNavigatorBundle.getString("xpinstallPromptAllowButton"), accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"), popup: null, callback: function() { - var mgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"] - .createInstance(Components.interfaces.nsIXPInstallManager); - mgr.initManagerWithInstallInfo(installInfo); + installInfo.install(); return false; } }]; } var notificationBox = gBrowser.getNotificationBox(browser); if (!notificationBox.getNotificationWithValue(notificationName)) { const priority = notificationBox.PRIORITY_WARNING_MEDIUM; @@ -1178,17 +1182,17 @@ function prepareForStartup() { OfflineApps, false); // setup simple gestures support gGestureSupport.init(true); } function delayedStartup(isLoadingBlank, mustLoadSidebar) { Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false); - Services.obs.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false); + Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false); BrowserOffline.init(); OfflineApps.init(); gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true); // Ensure login manager is up and running. Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); @@ -1396,17 +1400,17 @@ function BrowserShutdown() try { FullZoom.destroy(); } catch(ex) { Components.utils.reportError(ex); } Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history"); - Services.obs.removeObserver(gXPInstallObserver, "xpinstall-install-blocked"); + Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked"); Services.obs.removeObserver(gPluginHandler.pluginCrashed, "plugin-crashed"); try { gBrowser.removeProgressListener(window.XULBrowserWindow); gBrowser.removeTabsProgressListener(window.TabsProgressListener); } catch (ex) { }
--- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -252,17 +252,16 @@ @BINPATH@/components/xpcom_base.xpt @BINPATH@/components/xpcom_system.xpt @BINPATH@/components/xpcom_components.xpt @BINPATH@/components/xpcom_ds.xpt @BINPATH@/components/xpcom_io.xpt @BINPATH@/components/xpcom_threads.xpt @BINPATH@/components/xpcom_xpti.xpt @BINPATH@/components/xpconnect.xpt -@BINPATH@/components/xpinstall.xpt @BINPATH@/components/xulapp.xpt @BINPATH@/components/xuldoc.xpt @BINPATH@/components/xultmpl.xpt @BINPATH@/components/zipwriter.xpt ; JavaScript components @BINPATH@/components/FeedProcessor.js @BINPATH@/components/FeedConverter.js @@ -291,16 +290,18 @@ #endif @BINPATH@/components/nsHelperAppDlg.js @BINPATH@/components/nsDownloadManagerUI.js @BINPATH@/components/nsProxyAutoConfig.js @BINPATH@/components/NetworkGeolocationProvider.js @BINPATH@/components/GPSDGeolocationProvider.js @BINPATH@/components/nsSidebar.js @BINPATH@/components/addonManager.js +@BINPATH@/components/amContentHandler.js +@BINPATH@/components/amWebInstallListener.js @BINPATH@/components/nsBlocklistService.js #ifdef MOZ_UPDATER @BINPATH@/components/nsUpdateService.js @BINPATH@/components/nsUpdateServiceStub.js #endif @BINPATH@/components/nsUpdateTimerManager.js @BINPATH@/components/pluginGlue.js @BINPATH@/components/nsSessionStartup.js
--- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -121,17 +121,16 @@ MOZ_MAIL_NEWS = @MOZ_MAIL_NEWS@ MOZ_PLAINTEXT_EDITOR_ONLY = @MOZ_PLAINTEXT_EDITOR_ONLY@ BUILD_STATIC_LIBS = @BUILD_STATIC_LIBS@ MOZ_ENABLE_LIBXUL = @MOZ_ENABLE_LIBXUL@ ENABLE_TESTS = @ENABLE_TESTS@ IBMBIDI = @IBMBIDI@ MOZ_UNIVERSALCHARDET = @MOZ_UNIVERSALCHARDET@ ACCESSIBILITY = @ACCESSIBILITY@ MOZ_VIEW_SOURCE = @MOZ_VIEW_SOURCE@ -MOZ_XPINSTALL = @MOZ_XPINSTALL@ MOZ_JSLOADER = @MOZ_JSLOADER@ MOZ_USE_NATIVE_UCONV = @MOZ_USE_NATIVE_UCONV@ MOZ_BRANDING_DIRECTORY = @MOZ_BRANDING_DIRECTORY@ XPCOM_USE_LEA = @XPCOM_USE_LEA@ MOZ_ENABLE_POSTSCRIPT = @MOZ_ENABLE_POSTSCRIPT@ MOZ_INSTALLER = @MOZ_INSTALLER@ MOZ_UPDATER = @MOZ_UPDATER@ MOZ_UPDATE_PACKAGING = @MOZ_UPDATE_PACKAGING@
--- a/configure.in +++ b/configure.in @@ -4917,17 +4917,16 @@ MOZ_STORAGE=1 MOZ_SVG=1 MOZ_TIMELINE= MOZ_TOOLKIT_SEARCH=1 MOZ_UI_LOCALE=en-US MOZ_UNIVERSALCHARDET=1 MOZ_URL_CLASSIFIER= MOZ_USE_NATIVE_UCONV= MOZ_VIEW_SOURCE=1 -MOZ_XPINSTALL=1 MOZ_XSLT_STANDALONE= MOZ_XTF=1 MOZ_XUL=1 MOZ_ZIPWRITER=1 NS_PRINTING=1 NECKO_WIFI=1 NECKO_COOKIES=1 NECKO_DISK_CACHE=1 @@ -5736,27 +5735,16 @@ case "$target" in if test "$ac_cv_header_oleacc_idl" = "no"; then AC_MSG_ERROR([System header oleacc.idl is not available. See http://developer.mozilla.org/en/docs/oleacc.idl for details on fixing this problem.]) fi ;; esac fi dnl ======================================================== -dnl xpinstall support on by default -dnl ======================================================== -MOZ_ARG_DISABLE_BOOL(xpinstall, -[ --disable-xpinstall Disable xpinstall support], - MOZ_XPINSTALL=, - MOZ_XPINSTALL=1 ) -if test "$MOZ_XPINSTALL"; then - AC_DEFINE(MOZ_XPINSTALL) -fi - -dnl ======================================================== dnl xpcom js loader support on by default dnl ======================================================== if test "$MOZ_JSLOADER"; then AC_DEFINE(MOZ_JSLOADER) fi dnl ======================================================== dnl Disable printing @@ -6338,20 +6326,16 @@ if test -n "$MOZ_INSTALLER" -a "$OS_ARCH # The Windows build for NSIS requires the iconv command line utility to # convert the charset of the locale files. MOZ_PATH_PROGS(HOST_ICONV, $HOST_ICONV "iconv", "") if test -z "$HOST_ICONV"; then AC_MSG_ERROR([To build the installer iconv is required in your path. To build without the installer reconfigure using --disable-installer.]) fi fi -# Automatically disable installer if xpinstall isn't built -if test -z "$MOZ_XPINSTALL"; then - MOZ_INSTALLER= -fi AC_SUBST(MOZ_INSTALLER) AC_MSG_CHECKING([for tar archiver]) AC_CHECK_PROGS(TAR, gnutar gtar tar, "") if test -z "$TAR"; then AC_MSG_ERROR([no tar archiver found in \$PATH]) fi AC_MSG_RESULT([$TAR]) @@ -8421,17 +8405,16 @@ AC_SUBST(MOZ_XIE_LIBS) AC_SUBST(MOZ_ENABLE_POSTSCRIPT) AC_SUBST(BUILD_STATIC_LIBS) AC_SUBST(MOZ_ENABLE_LIBXUL) AC_SUBST(ENABLE_TESTS) AC_SUBST(IBMBIDI) AC_SUBST(MOZ_UNIVERSALCHARDET) AC_SUBST(ACCESSIBILITY) -AC_SUBST(MOZ_XPINSTALL) AC_SUBST(MOZ_VIEW_SOURCE) AC_SUBST(MOZ_SPELLCHECK) AC_SUBST(MOZ_USER_DIR) AC_SUBST(MOZ_CRASHREPORTER) AC_SUBST(ENABLE_STRIP) AC_SUBST(PKG_SKIP_STRIP) AC_SUBST(USE_ELF_DYNSTR_GC)
--- a/modules/libpref/src/Makefile.in +++ b/modules/libpref/src/Makefile.in @@ -80,17 +80,17 @@ EXTRA_DSO_LDOPTS = \ include $(topsrcdir)/config/rules.mk GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/, \ mailnews.js editor.js \ aix.js beos.js unix.js winpref.js os2prefs.js openvms.js photon.js) GARBAGE += greprefs.js -GREPREF_FILES = $(topsrcdir)/xpinstall/public/xpinstall.js $(topsrcdir)/netwerk/base/public/security-prefs.js $(srcdir)/init/all.js +GREPREF_FILES = $(topsrcdir)/netwerk/base/public/security-prefs.js $(srcdir)/init/all.js # Optimizer bug with GCC 3.2.2 on OS/2 ifeq ($(OS_ARCH), OS2) nsPrefService.$(OBJ_SUFFIX): nsPrefService.cpp $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CXX) $(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS:-O2=-O1) $(_VPATH_SRCS) endif
--- a/netwerk/confvars.sh +++ b/netwerk/confvars.sh @@ -34,9 +34,8 @@ # 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 ***** MOZ_APP_NAME=mozilla MOZ_EXTENSIONS_DEFAULT="" MOZ_APP_VERSION=$MOZILLA_VERSION -MOZ_XPINSTALL=
--- a/toolkit/library/libxul-config.mk +++ b/toolkit/library/libxul-config.mk @@ -118,22 +118,20 @@ STATIC_LIBS += \ gfxutils \ $(NULL) ifdef MOZ_IPC STATIC_LIBS += chromium_s endif ifndef WINCE -ifdef MOZ_XPINSTALL STATIC_LIBS += \ mozreg_s \ $(NULL) endif -endif # component libraries COMPONENT_LIBS += \ xpconnect \ necko \ uconv \ i18n \ chardet \ @@ -145,16 +143,17 @@ COMPONENT_LIBS += \ gklayout \ docshell \ embedcomponents \ webbrwsr \ nsappshell \ txmgr \ chrome \ commandlines \ + extensions \ toolkitcomps \ pipboot \ pipnss \ appcomps \ $(NULL) ifdef BUILD_CTYPES COMPONENT_LIBS += \ @@ -192,23 +191,16 @@ endif endif ifneq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT))) COMPONENT_LIBS += \ windowsproxy \ $(NULL) endif -ifdef MOZ_XPINSTALL -DEFINES += -DMOZ_XPINSTALL -COMPONENT_LIBS += \ - xpinstall \ - $(NULL) -endif - ifdef MOZ_JSDEBUGGER DEFINES += -DMOZ_JSDEBUGGER COMPONENT_LIBS += \ jsd \ $(NULL) endif ifdef MOZ_PREF_EXTENSIONS
--- a/toolkit/library/nsStaticXULComponents.cpp +++ b/toolkit/library/nsStaticXULComponents.cpp @@ -139,23 +139,16 @@ #ifdef MOZ_PLUGINS #define PLUGINS_MODULES \ MODULE(nsPluginModule) #else #define PLUGINS_MODULES #endif -#ifdef MOZ_XPINSTALL -#define XPINSTALL_MODULES \ - MODULE(nsSoftwareUpdate) -#else -#define XPINSTALL_MODULES -#endif - #ifdef MOZ_JSDEBUGGER #define JSDEBUGGER_MODULES \ MODULE(JavaScript_Debugger) #else #define JSDEBUGGER_MODULES #endif #if defined(MOZ_FILEVIEW) && defined(MOZ_XUL) @@ -264,19 +257,19 @@ MODULE(nsChromeModule) \ MODULE(application) \ MODULE(Apprunner) \ MODULE(CommandLineModule) \ FILEVIEW_MODULE \ STORAGE_MODULE \ PLACES_MODULES \ XULENABLED_MODULES \ + MODULE(AddonsModule) \ MODULE(nsToolkitCompsModule) \ XREMOTE_MODULES \ - XPINSTALL_MODULES \ JSDEBUGGER_MODULES \ MODULE(BOOT) \ MODULE(NSS) \ SYSTEMPREF_MODULES \ SPELLCHECK_MODULE \ LAYOUT_DEBUG_MODULE \ UNIXPROXY_MODULE \ OSXPROXY_MODULE \
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/amContentHandler.js @@ -0,0 +1,97 @@ +/* +# ***** 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 the Extension Manager. +# +# The Initial Developer of the Original Code is +# the Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2010 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Dave Townsend <dtownsend@oxymoronical.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 Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +const XPI_CONTENT_TYPE = "application/x-xpinstall"; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +function amContentHandler() { +} + +amContentHandler.prototype = { + /** + * Handles a new request for an application/x-xpinstall file. + * + * @param mimetype + * The mimetype of the file + * @param context + * The context passed to nsIChannel.asyncOpen + */ + handleContent: function XCH_handleContent(mimetype, context, request) { + if (mimetype != XPI_CONTENT_TYPE) + throw Cr.NS_ERROR_WONT_HANDLE_CONTENT; + + if (!(request instanceof Ci.nsIChannel)) + throw Cr.NS_ERROR_WONT_HANDLE_CONTENT; + + let uri = request.URI; + + let referer = null; + if (request instanceof Ci.nsIPropertyBag2) { + referer = request.getPropertyAsInterface("docshell.internalReferrer", + Ci.nsIURI); + } + + let window = null; + let callbacks = request.notificationCallbacks ? + request.notificationCallbacks : + request.loadGroup.notificationCallbacks; + if (callbacks) + window = callbacks.getInterface(Ci.nsIDOMWindow); + + request.cancel(Cr.NS_BINDING_ABORTED); + + let manager = Cc["@mozilla.org/addons/integration;1"]. + getService(Ci.amIWebInstaller); + manager.installAddonsFromWebpage(mimetype, window, referer, [uri.spec], + [null], [null], [null], null, 1); + }, + + classDescription: "XPI Content Handler", + contractID: "@mozilla.org/uriloader/content-handler;1?type=" + XPI_CONTENT_TYPE, + classID: Components.ID("{7beb3ba8-6ec3-41b4-b67c-da89b8518922}"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler]) +}; + +function NSGetModule(compMgr, fileSpec) + XPCOMUtils.generateModule([amContentHandler]);
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/amIInstallTrigger.idl @@ -0,0 +1,126 @@ +/* ***** 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 the Extension Manager. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dave Townsend <dtownsend@oxymoronical.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 ***** */ + +#include "nsISupports.idl" + +interface nsIVariant; + +/** + * A callback function that webpages can implement to be notified when triggered + * installs complete. + */ +[scriptable, function, uuid(bb22f5c0-3ca1-48f6-873c-54e87987700f)] +interface amIInstallCallback : nsISupports +{ + /** + * Called when an install completes or fails. + * @param url + * The url of the add-on being installed + * @param status + * 0 if the install was successful or negative if not + */ + void onInstallEnded(in AString url, in PRInt32 status); +}; + +/** + * The interface for the InstallTrigger object available to all websites. + */ +[scriptable, uuid(14b4e84d-001c-4403-a608-52a67ffaab40)] +interface amIInstallTrigger : nsISupports +{ + /** + * Retained for backwards compatibility. + */ + const PRUint32 SKIN = 1; + const PRUint32 LOCALE = 2; + const PRUint32 CONTENT = 4; + const PRUint32 PACKAGE = 7; + + /** + * Tests if installation is enabled. This method is deprecated, please use + * "enabled" in the future. + */ + boolean updateEnabled(); + + /** + * Tests if installation is enabled. + */ + boolean enabled(); + + /** + * Starts a new installation of a set of add-ons. + * + * @param args + * The add-ons to install. This should be a JS object, each property + * is the name of an add-on to be installed. The value of the + * property should either be a string URL, or an object with the + * following properties: + * * URL for the add-on's URL + * * IconURL for an icon for the add-on + * * Hash for a hash of the add-on + * @param callback + * A callback to call as each installation succeeds or fails + * @return true if the installations were successfully started + */ + boolean install(in nsIVariant args, [optional] in amIInstallCallback callback); + + /** + * Starts installing a new add-on. This method is deprecated, please use + * "install" in the future. + * + * @param type + * Unused, retained for backwards compatibility + * @param url + * The URL of the add-on + * @param skin + * Unused, retained for backwards compatibility + * @return true if the installation was successfully started + */ + boolean installChrome(in PRUint32 type, in AString url, in AString skin); + + /** + * Starts installing a new add-on. This method is deprecated, please use + * "install" in the future. + * + * @param url + * The URL of the add-on + * @param flags + * Unused, retained for backwards compatibility + * @return true if the installation was successfully started + */ + boolean startSoftwareUpdate(in AString url, [optional] in PRInt32 flags); +};
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/amIWebInstallListener.idl @@ -0,0 +1,105 @@ +/* ***** 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 the Extension Manager. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dave Townsend <dtownsend@oxymoronical.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 ***** */ + +#include "nsISupports.idl" + +interface nsIDOMWindowInternal; +interface nsIURI; +interface nsIVariant; + +/** + * amIWebInstallInfo is used by the default implementation of + * amIWebInstallListener to communicate with the running application and allow + * it to warn the user about blocked installs and start the installs running. + */ +[scriptable, uuid(8710e692-3989-4dc7-b607-40d57610ae75)] +interface amIWebInstallInfo : nsISupports +{ + readonly attribute nsIDOMWindowInternal originatingWindow; + readonly attribute nsIURI originatingURI; + readonly attribute nsIVariant installs; + + /** + * Starts all installs. + */ + void install(); +}; + +/** + * The registered amIWebInstallListener is used to notify about new installs + * triggered by websites. The default implementation displays a confirmation + * dialog when add-ons are ready to install and uses the observer service to + * notify when installations are blocked. + */ +[scriptable, uuid(ea806f3a-1b27-4d3d-9aee-88dec4c29fda)] +interface amIWebInstallListener : nsISupports +{ + /** + * Called when the website is not allowed to directly prompt the user to + * install add-ons. + * + * @param window + * The window that triggered the installs + * @param uri + * The URI of the site that triggered the installs + * @param installs + * The AddonInstalls that were blocked + * @param count + * The number of AddonInstalls + * @return true if the caller should start the installs + */ + boolean onWebInstallBlocked(in nsIDOMWindowInternal window, in nsIURI uri, + [array, size_is(count)] in nsIVariant installs, + [optional] in PRUint32 count); + + /** + * Called when a website wants to ask the user to install add-ons. + * + * @param window + * The window that triggered the installs + * @param uri + * The URI of the site that triggered the installs + * @param installs + * The AddonInstalls that were requested + * @param count + * The number of AddonInstalls + * @return true if the caller should start the installs + */ + boolean onWebInstallRequested(in nsIDOMWindowInternal window, in nsIURI uri, + [array, size_is(count)] in nsIVariant installs, + [optional] in PRUint32 count); +};
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/amInstallTrigger.cpp @@ -0,0 +1,398 @@ +/* ***** 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 the Extension Manager. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dave Townsend <dtownsend@oxymoronical.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 ***** */ + +#include "amInstallTrigger.h" +#include "nsIClassInfoImpl.h" +#include "nsIGenericFactory.h" +#include "nsIComponentManager.h" +#include "nsIComponentRegistrar.h" +#include "nsICategoryManager.h" +#include "nsServiceManagerUtils.h" +#include "nsXPIDLString.h" +#include "nsIScriptNameSpaceManager.h" +#include "nsDOMJSUtils.h" +#include "nsIXPConnect.h" +#include "nsContentUtils.h" +#include "nsIDocument.h" +#include "nsIDOMDocument.h" +#include "nsNetUtil.h" +#include "nsIScriptSecurityManager.h" + +// +// Helper function for URI verification +// +static nsresult +CheckLoadURIFromScript(JSContext *cx, const nsACString& uriStr) +{ + nsresult rv; + nsCOMPtr<nsIScriptSecurityManager> secman(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + // get the script principal + nsCOMPtr<nsIPrincipal> principal; + rv = secman->GetSubjectPrincipal(getter_AddRefs(principal)); + NS_ENSURE_SUCCESS(rv, rv); + if (!principal) + return NS_ERROR_FAILURE; + + // convert the requested URL string to a URI + // Note that we use a null base URI here, since that's what we use when we + // actually convert the string into a URI to load. + nsCOMPtr<nsIURI> uri; + rv = NS_NewURI(getter_AddRefs(uri), uriStr); + NS_ENSURE_SUCCESS(rv, rv); + + // are we allowed to load this one? + rv = secman->CheckLoadURIWithPrincipal(principal, uri, + nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL); + return rv; +} + +NS_IMPL_ISUPPORTS1_CI(amInstallTrigger, amIInstallTrigger) + +amInstallTrigger::amInstallTrigger() +{ + mManager = do_GetService("@mozilla.org/addons/integration;1"); +} + +amInstallTrigger::~amInstallTrigger() +{ +} + +JSContext* +amInstallTrigger::GetJSContext() +{ + nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); + + // get the xpconnect native call context + nsAXPCNativeCallContext *cc = nsnull; + xpc->GetCurrentNativeCallContext(&cc); + if (!cc) + return nsnull; + + // Get JSContext of current call + JSContext* cx; + nsresult rv = cc->GetJSContext(&cx); + if (NS_FAILED(rv)) + return nsnull; + + return cx; +} + +already_AddRefed<nsIDOMWindowInternal> +amInstallTrigger::GetOriginatingWindow(JSContext* cx) +{ + nsIScriptGlobalObject *globalObject = nsnull; + nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx); + if (!scriptContext) + return nsnull; + + globalObject = scriptContext->GetGlobalObject(); + if (!globalObject) + return nsnull; + + nsCOMPtr<nsIDOMWindowInternal> window = do_QueryInterface(globalObject); + return window.forget(); +} + +already_AddRefed<nsIURI> +amInstallTrigger::GetOriginatingURI(nsIDOMWindowInternal* aWindow) +{ + if (!aWindow) + return nsnull; + + nsCOMPtr<nsIDOMDocument> domdoc; + aWindow->GetDocument(getter_AddRefs(domdoc)); + nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc)); + nsIURI* uri = doc->GetDocumentURI(); + NS_IF_ADDREF(uri); + return uri; +} + +/* boolean updateEnabled (); */ +NS_IMETHODIMP +amInstallTrigger::UpdateEnabled(PRBool *_retval NS_OUTPARAM) +{ + return Enabled(_retval); +} + +/* boolean enabled (); */ +NS_IMETHODIMP +amInstallTrigger::Enabled(PRBool *_retval NS_OUTPARAM) +{ + nsCOMPtr<nsIDOMWindowInternal> window = GetOriginatingWindow(GetJSContext()); + nsCOMPtr<nsIURI> referer = GetOriginatingURI(window); + + return mManager->IsInstallEnabled(NS_LITERAL_STRING("application/x-xpinstall"), referer, _retval); +} + +/* boolean install (in nsIVariant args, [optional] in amIInstallCallback callback); */ +NS_IMETHODIMP +amInstallTrigger::Install(nsIVariant *args, + amIInstallCallback *callback, + PRBool *_retval NS_OUTPARAM) +{ + JSContext *cx = GetJSContext(); + nsCOMPtr<nsIDOMWindowInternal> window = GetOriginatingWindow(cx); + nsCOMPtr<nsIURI> referer = GetOriginatingURI(window); + + jsval params; + nsresult rv = args->GetAsJSVal(¶ms); + NS_ENSURE_SUCCESS(rv, rv); + + if (!JSVAL_IS_OBJECT(params) || !JSVAL_TO_OBJECT(params)) + return NS_ERROR_INVALID_ARG; + + JSIdArray *ida = JS_Enumerate(cx, JSVAL_TO_OBJECT(params)); + if (!ida) + return NS_ERROR_FAILURE; + + PRUint32 count = ida->length; + + nsTArray<const PRUnichar*> names; + nsTArray<const PRUnichar*> uris; + nsTArray<const PRUnichar*> icons; + nsTArray<const PRUnichar*> hashes; + + jsval v; + for (PRUint32 i = 0; i < count; i++ ) { + JS_IdToValue(cx, ida->vector[i], &v); + JSString *str = JS_ValueToString(cx, v); + if (!str) { + JS_DestroyIdArray(cx, ida); + return NS_ERROR_FAILURE; + } + + const PRUnichar* name = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); + const PRUnichar* uri = nsnull; + const PRUnichar* icon = nsnull; + const PRUnichar* hash = nsnull; + + JS_GetUCProperty(cx, JSVAL_TO_OBJECT(params), reinterpret_cast<const jschar*>(name), nsCRT::strlen(name), &v); + if (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v)) { + jsval v2; + if (JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "URL", &v2) && !JSVAL_IS_VOID(v2)) { + JSString *str = JS_ValueToString(cx, v2); + if (!str) { + JS_DestroyIdArray(cx, ida); + return NS_ERROR_FAILURE; + } + uri = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); + } + + if (JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "IconURL", &v2) && !JSVAL_IS_VOID(v2)) { + JSString *str = JS_ValueToString(cx, v2); + if (!str) { + JS_DestroyIdArray(cx, ida); + return NS_ERROR_FAILURE; + } + icon = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); + } + + if (JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "Hash", &v2) && !JSVAL_IS_VOID(v2)) { + JSString *str = JS_ValueToString(cx, v2); + if (!str) { + JS_DestroyIdArray(cx, ida); + return NS_ERROR_FAILURE; + } + hash = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); + } + } + else { + uri = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(JS_ValueToString(cx, v))); + } + + if (!uri) { + JS_DestroyIdArray(cx, ida); + return NS_ERROR_FAILURE; + } + + nsCString tmpURI = NS_ConvertUTF16toUTF8(uri); + // Get relative URL to load + if (referer) { + rv = referer->Resolve(tmpURI, tmpURI); + if (NS_FAILED(rv)) { + JS_DestroyIdArray(cx, ida); + return rv; + } + } + + rv = CheckLoadURIFromScript(cx, tmpURI); + if (NS_FAILED(rv)) { + JS_DestroyIdArray(cx, ida); + return rv; + } + uri = UTF8ToNewUnicode(tmpURI); + + if (icon) { + nsCString tmpIcon = NS_ConvertUTF16toUTF8(icon); + if (referer) { + rv = referer->Resolve(tmpIcon, tmpIcon); + if (NS_FAILED(rv)) { + JS_DestroyIdArray(cx, ida); + return rv; + } + } + + // If the page can't load the icon then just ignore it + rv = CheckLoadURIFromScript(cx, tmpIcon); + if (NS_FAILED(rv)) + icon = nsnull; + else + icon = UTF8ToNewUnicode(tmpIcon); + } + + names.AppendElement(name); + uris.AppendElement(uri); + icons.AppendElement(icon); + hashes.AppendElement(hash); + } + + JS_DestroyIdArray(cx, ida); + + rv = mManager->InstallAddonsFromWebpage(NS_LITERAL_STRING("application/x-xpinstall"), + window, referer, uris.Elements(), + hashes.Elements(), names.Elements(), + icons.Elements(), callback, count, + _retval); + + for (PRUint32 i = 0; i < uris.Length(); i++) { + NS_Free(const_cast<PRUnichar*>(uris[i])); + if (icons[i]) + NS_Free(const_cast<PRUnichar*>(icons[i])); + } + + return rv; +} + +/* boolean installChrome (in PRUint32 type, in AString url, in AString skin); */ +NS_IMETHODIMP +amInstallTrigger::InstallChrome(PRUint32 type, + const nsAString & url, + const nsAString & skin, + PRBool *_retval NS_OUTPARAM) +{ + return StartSoftwareUpdate(url, 0, _retval); +} + +/* boolean startSoftwareUpdate (in AString url, [optional] in PRInt32 flags); */ +NS_IMETHODIMP +amInstallTrigger::StartSoftwareUpdate(const nsAString & url, + PRInt32 flags, + PRBool *_retval NS_OUTPARAM) +{ + nsresult rv; + + JSContext *cx = GetJSContext(); + nsCOMPtr<nsIDOMWindowInternal> window = GetOriginatingWindow(cx); + nsCOMPtr<nsIURI> referer = GetOriginatingURI(window); + + nsTArray<const PRUnichar*> names; + nsTArray<const PRUnichar*> uris; + nsTArray<const PRUnichar*> icons; + nsTArray<const PRUnichar*> hashes; + + nsCString tmpURI = NS_ConvertUTF16toUTF8(url); + // Get relative URL to load + if (referer) { + rv = referer->Resolve(tmpURI, tmpURI); + NS_ENSURE_SUCCESS(rv, rv); + } + + rv = CheckLoadURIFromScript(cx, tmpURI); + NS_ENSURE_SUCCESS(rv, rv); + + names.AppendElement((PRUnichar*)nsnull); + uris.AppendElement(UTF8ToNewUnicode(tmpURI)); + icons.AppendElement((PRUnichar*)nsnull); + hashes.AppendElement((PRUnichar*)nsnull); + + rv = mManager->InstallAddonsFromWebpage(NS_LITERAL_STRING("application/x-xpinstall"), + window, referer, uris.Elements(), + hashes.Elements(), names.Elements(), + icons.Elements(), nsnull, 1, _retval); + + NS_Free(const_cast<PRUnichar*>(uris[0])); + return rv; +} + +NS_DECL_CLASSINFO(amInstallTrigger) + +NS_GENERIC_FACTORY_CONSTRUCTOR(amInstallTrigger) + +static NS_METHOD +RegisterInstallTrigger(nsIComponentManager *aCompMgr, + nsIFile *aPath, + const char *registryLocation, + const char *componentType, + const nsModuleComponentInfo *info) +{ + nsresult rv = NS_OK; + + nsCOMPtr<nsICategoryManager> catman = + do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsXPIDLCString previous; + rv = catman->AddCategoryEntry(JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY, + "InstallTrigger", + AM_INSTALLTRIGGER_CONTRACTID, + PR_TRUE, PR_TRUE, getter_Copies(previous)); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + + +// The list of components we register +static const nsModuleComponentInfo components[] = +{ + { "InstallTrigger Component", + AM_InstallTrigger_CID, + AM_INSTALLTRIGGER_CONTRACTID, + amInstallTriggerConstructor, + RegisterInstallTrigger, + nsnull, // unregister + nsnull, // factory destructor + NS_CI_INTERFACE_GETTER_NAME(amInstallTrigger), + nsnull, // language helper + &NS_CLASSINFO_NAME(amInstallTrigger), + nsIClassInfo::DOM_OBJECT // flags + } +}; + +NS_IMPL_NSGETMODULE(AddonsModule, components)
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/amInstallTrigger.h @@ -0,0 +1,65 @@ +/* ***** 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 the Extension Manager. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dave Townsend <dtownsend@oxymoronical.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 ***** */ + +#include "jscntxt.h" +#include "amIInstallTrigger.h" +#include "nsIDOMWindowInternal.h" +#include "nsIURI.h" +#include "amIWebInstaller.h" +#include "nsCOMPtr.h" + +#define AM_InstallTrigger_CID \ + {0xfcfcdf1e, 0xe9ef, 0x4141, {0x90, 0xd8, 0xd5, 0xff, 0x84, 0xc1, 0x7c, 0xce}} +#define AM_INSTALLTRIGGER_CONTRACTID "@mozilla.org/addons/installtrigger;1" + +class amInstallTrigger : public amIInstallTrigger +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_AMIINSTALLTRIGGER + + amInstallTrigger(); + +private: + ~amInstallTrigger(); + + JSContext* GetJSContext(); + already_AddRefed<nsIDOMWindowInternal> GetOriginatingWindow(JSContext* cx); + already_AddRefed<nsIURI> GetOriginatingURI(nsIDOMWindowInternal* aWindow); + + nsCOMPtr<amIWebInstaller> mManager; +};
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/amWebInstallListener.js @@ -0,0 +1,221 @@ +/* +# ***** 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 the Extension Manager. +# +# The Initial Developer of the Original Code is +# the Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2010 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Dave Townsend <dtownsend@oxymoronical.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 ***** +*/ + +/** + * This is a default implementation of amIWebInstallListener that should work + * for most applications but can be overriden. It notifies the observer service + * about blocked installs. For normal installs it pops up an install + * confirmation when all the add-ons have been downloaded. + */ + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/AddonManager.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +/** + * Logs a warning message + * + * @param str + * The string to log + */ +function WARN(str) { + dump("*** addons.weblistener: " + str + "\n"); +} + +/** + * Creates a new installer to monitor downloads and prompt to install when + * ready + * + * @param window + * The window that started the installations + * @param url + * The URL that started the installations + * @installs installs + * An array of AddonInstalls + */ +function Installer(window, url, installs) { + this.window = window; + this.url = url; + this.downloads = installs; + this.installs = []; + + this.bundle = Cc["@mozilla.org/intl/stringbundle;1"]. + getService(Ci.nsIStringBundleService). + createBundle("chrome://mozapps/locale/extensions/extensions.properties"); + + this.count = installs.length; + installs.forEach(function(install) { + install.addListener(this); + + // Might already be a local file + if (install.state == AddonManager.STATE_DOWNLOADED) + this.onDownloadEnded(install); + else + install.install(); + }, this); +} + +Installer.prototype = { + window: null, + downloads: null, + installs: null, + count: null, + + /** + * Checks if all downloads are now complete and if so prompts to install. + */ + checkAllDownloaded: function() { + if (--this.count > 0) + return; + + // Maybe none of the downloads were sucessful + if (this.installs.length == 0) + return; + + let args = {}; + args.url = this.url; + args.installs = this.installs; + args.wrappedJSObject = args; + + Services.ww.openWindow(this.window, "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul", + null, "chrome,modal,centerscreen", args); + }, + + onDownloadCancelled: function(install) { + install.removeListener(this); + + this.checkAllDownloaded(); + }, + + onDownloadFailed: function(install, error) { + install.removeListener(this); + + // TODO show some better error + Services.prompt.alert(this.window, "Download Failed", "The download of " + install.sourceURL + " failed: " + error); + this.checkAllDownloaded(); + }, + + onDownloadEnded: function(install) { + install.removeListener(this); + + if (install.addon.appDisabled) { + // App disabled items are not compatible + install.cancel(); + + let title = null; + let text = null; + + let problems = ""; + if (!install.addon.isCompatible) + problems += "incompatible, "; + if (!install.addon.providesUpdatesSecurely) + problems += "insecure updates, "; + if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) { + problems += "blocklisted, "; + title = bundle.GetStringFromName("blocklistedInstallTitle2"); + text = this.bundle.formatStringFromName("blocklistedInstallMsg2", + [install.addon.name], 1); + } + problems = problems.substring(0, problems.length - 2); + WARN("Not installing " + install.addon.id + " because of the following: " + problems); + + title = this.bundle.GetStringFromName("incompatibleTitle2", 1); + text = this.bundle.formatStringFromName("incompatibleMessage", + [install.addon.name, + install.addon.version, + Services.appinfo.name, + Services.appinfo.version], 4); + Services.prompt.alert(this.window, title, text); + } + else { + this.installs.push(install); + } + + this.checkAllDownloaded(); + return false; + }, +}; + +function extWebInstallListener() { +} + +extWebInstallListener.prototype = { + /** + * @see amIWebInstallListener.idl + */ + onWebInstallBlocked: function(window, uri, installs) { + let info = { + originatingWindow: window, + originatingURI: uri, + installs: installs, + + install: function() { + dump("Start installs\n"); + new Installer(this.originatingWindow, this.originatingURI, this.installs); + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo]) + }; + Services.obs.notifyObservers(info, "addon-install-blocked", null); + + return false; + }, + + /** + * @see amIWebInstallListener.idl + */ + onWebInstallRequested: function(window, uri, installs) { + new Installer(window, uri, installs); + + // We start the installs ourself + return false; + }, + + classDescription: "XPI Install Handler", + contractID: "@mozilla.org/addons/web-install-listener;1", + classID: Components.ID("{0f38e086-89a3-40a5-8ffc-9b694de1d04a}"), + QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallListener]) +}; + +function NSGetModule(compMgr, fileSpec) + XPCOMUtils.generateModule([extWebInstallListener]);
--- a/toolkit/mozapps/xpinstall/content/xpinstallConfirm.js +++ b/toolkit/mozapps/xpinstall/content/xpinstallConfirm.js @@ -30,70 +30,63 @@ # 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 ***** -var XPInstallConfirm = -{ - _param: null -}; +var args +var XPInstallConfirm = {}; XPInstallConfirm.init = function () { var _installCountdown; var _installCountdownInterval; var _focused; var _timeout; var bundle = document.getElementById("xpinstallConfirmStrings"); - - this._param = window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock); - if (!this._param) - close(); - - this._param.SetInt(0, 1); // The default return value is "Cancel" - + + args = window.arguments[0].wrappedJSObject; + var _installCountdownLength = 5; try { var prefs = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); var delay_in_milliseconds = prefs.getIntPref("security.dialog_enable_delay"); _installCountdownLength = Math.round(delay_in_milliseconds / 500); } catch (ex) { } var itemList = document.getElementById("itemList"); - var numItemsToInstall = this._param.GetInt(1); + var numItemsToInstall = args.installs.length; for (var i = 0; i < numItemsToInstall; ++i) { var installItem = document.createElement("installitem"); itemList.appendChild(installItem); - installItem.name = this._param.GetString(i); - installItem.url = this._param.GetString(++i); - var icon = this._param.GetString(++i); - if (icon != "") + installItem.name = args.installs[i].addon.name; + installItem.url = args.installs[i].sourceURL; + var icon = args.installs[i].iconURL; + if (icon != null) installItem.icon = icon; - var cert = this._param.GetString(++i); - if (cert) - installItem.cert = bundle.getFormattedString("signed", [cert]); - else + if (args.installs[i].certName) { + installItem.cert = bundle.getFormattedString("signed", [args.installs[i].certName]); + } + else { installItem.cert = bundle.getString("unverified"); - installItem.signed = cert ? "true" : "false"; + } + installItem.signed = args.installs[i].certName ? "true" : "false"; } var introString = bundle.getString("itemWarnIntroSingle"); if (numItemsToInstall > 4) introString = bundle.getFormattedString("itemWarnIntroMultiple", [numItemsToInstall / 4]); - if (this._param.objects && this._param.objects.length) - introString = this._param.objects.queryElementAt(0, Components.interfaces.nsISupportsString).data; var textNode = document.createTextNode(introString); var introNode = document.getElementById("itemWarningIntro"); while (introNode.hasChildNodes()) introNode.removeChild(introNode.firstChild); introNode.appendChild(textNode); var okButton = document.documentElement.getButton("accept"); okButton.focus(); @@ -168,17 +161,21 @@ XPInstallConfirm.init = function () setWidgetsAfterFocus(); } else okButton.label = bundle.getString("installButtonLabel"); } XPInstallConfirm.onOK = function () { - this._param.SetInt(0, 0); + args.installs.forEach(function(install) { + install.install(); + }); return true; } XPInstallConfirm.onCancel = function () { - this._param.SetInt(0, 1); + args.installs.forEach(function(install) { + install.cancel(); + }); return true; }
--- a/toolkit/toolkit-makefiles.sh +++ b/toolkit/toolkit-makefiles.sh @@ -549,22 +549,16 @@ MAKEFILES_xpcom=" MAKEFILES_xpcom_tests=" xpcom/tests/Makefile xpcom/tests/dynamic/Makefile xpcom/tests/services/Makefile xpcom/tests/windows/Makefile xpcom/tests/static-checker/Makefile " -MAKEFILES_xpinstall=" - xpinstall/Makefile - xpinstall/public/Makefile - xpinstall/src/Makefile -" - MAKEFILES_xpfe=" widget/src/xremoteclient/Makefile toolkit/components/remote/Makefile xpfe/components/Makefile xpfe/components/directory/Makefile xpfe/components/autocomplete/Makefile xpfe/components/autocomplete/public/Makefile xpfe/components/autocomplete/src/Makefile @@ -836,17 +830,16 @@ add_makefiles " $MAKEFILES_caps $MAKEFILES_chrome $MAKEFILES_view $MAKEFILES_docshell $MAKEFILES_webshell $MAKEFILES_widget $MAKEFILES_xpcom $MAKEFILES_xpcom_tests - $MAKEFILES_xpinstall $MAKEFILES_xpfe $MAKEFILES_embedding $MAKEFILES_xulapp $MAKEFILES_libpr0n $MAKEFILES_accessible $MAKEFILES_zlib $MAKEFILES_libmar $MAKEFILES_lib7z @@ -999,17 +992,16 @@ if [ "$ENABLE_TESTS" ]; then toolkit/mozapps/plugins/tests/Makefile toolkit/mozapps/update/test/Makefile toolkit/spatial-navigation/tests/Makefile toolkit/xre/test/Makefile uriloader/exthandler/tests/mochitest/Makefile widget/tests/Makefile xpcom/sample/program/Makefile xpcom/tests/external/Makefile - xpinstall/tests/Makefile " fi if [ "$MOZ_ZIPWRITER" ]; then add_makefiles " modules/libjar/zipwriter/Makefile modules/libjar/zipwriter/public/Makefile modules/libjar/zipwriter/src/Makefile
--- a/toolkit/toolkit-tiers.mk +++ b/toolkit/toolkit-tiers.mk @@ -54,20 +54,18 @@ endif tier_platform_dirs += xpcom ifndef MOZ_NATIVE_ZLIB tier_platform_dirs += modules/zlib endif ifndef WINCE -ifneq (,$(MOZ_XPINSTALL)) tier_platform_dirs += modules/libreg endif -endif tier_platform_dirs += \ modules/libpref \ intl \ netwerk \ $(NULL) ifdef MOZ_AUTH_EXTENSION @@ -209,20 +207,16 @@ tier_platform_dirs += widget/src/xremote endif ifdef MOZ_SPELLCHECK tier_platform_dirs += extensions/spellcheck endif tier_platform_dirs += toolkit -ifdef MOZ_XPINSTALL -tier_platform_dirs += xpinstall -endif - ifdef MOZ_PSM tier_platform_dirs += security/manager else tier_platform_dirs += security/manager/boot/public security/manager/ssl/public endif ifdef MOZ_PREF_EXTENSIONS tier_platform_dirs += extensions/pref