From 5f5d16d6d97f706e0519a0688b2cbb2e27b45687 Mon Sep 17 00:00:00 2001 From: "ben%bengoodger.com" Date: Wed, 1 Dec 2004 05:59:04 +0000 Subject: [PATCH] aviary branch landing: - xpinstall hooks for extension manager (242529, r=dveditz) (install.rdf read hook + stub extension manager implementation for seamonkey) - xpinstall hooks for info bar (xpinstall whitelist UI) --- xpfe/components/Makefile.in | 1 + xpfe/components/extensions/Makefile.in | 0 xpfe/components/extensions/public/Makefile.in | 0 .../extensions/public/nsIExtensionManager.idl | 0 xpfe/components/extensions/src/Makefile.in | 0 .../extensions/src/nsExtensionManager.js | 0 xpinstall/packager/packages-static-unix | 2 + xpinstall/packager/packages-static-win | 2 + xpinstall/packager/packages-unix | 2 + xpinstall/packager/packages-win | 2 + xpinstall/public/Makefile.in | 1 + xpinstall/public/nsIXPInstallManager.idl | 60 ++++ xpinstall/public/nsSoftwareUpdateIIDs.h | 8 +- xpinstall/src/nsInstall.cpp | 27 +- xpinstall/src/nsInstall.h | 10 +- xpinstall/src/nsInstallTrigger.cpp | 45 ++- xpinstall/src/nsSoftwareUpdate.cpp | 42 ++- xpinstall/src/nsSoftwareUpdateRun.cpp | 267 ++++++++++++------ xpinstall/src/nsXPInstallManager.cpp | 93 ++++-- xpinstall/src/nsXPInstallManager.h | 7 +- 20 files changed, 417 insertions(+), 152 deletions(-) create mode 100644 xpfe/components/extensions/Makefile.in create mode 100644 xpfe/components/extensions/public/Makefile.in create mode 100644 xpfe/components/extensions/public/nsIExtensionManager.idl create mode 100644 xpfe/components/extensions/src/Makefile.in create mode 100644 xpfe/components/extensions/src/nsExtensionManager.js create mode 100644 xpinstall/public/nsIXPInstallManager.idl diff --git a/xpfe/components/Makefile.in b/xpfe/components/Makefile.in index 2498b68c1b0..91071ed3d19 100644 --- a/xpfe/components/Makefile.in +++ b/xpfe/components/Makefile.in @@ -124,6 +124,7 @@ DIRS = \ sidebar/public \ bookmarks/public \ alerts \ + extensions \ $(NULL) ifeq ($(OS_ARCH),WINNT) diff --git a/xpfe/components/extensions/Makefile.in b/xpfe/components/extensions/Makefile.in new file mode 100644 index 00000000000..e69de29bb2d diff --git a/xpfe/components/extensions/public/Makefile.in b/xpfe/components/extensions/public/Makefile.in new file mode 100644 index 00000000000..e69de29bb2d diff --git a/xpfe/components/extensions/public/nsIExtensionManager.idl b/xpfe/components/extensions/public/nsIExtensionManager.idl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/xpfe/components/extensions/src/Makefile.in b/xpfe/components/extensions/src/Makefile.in new file mode 100644 index 00000000000..e69de29bb2d diff --git a/xpfe/components/extensions/src/nsExtensionManager.js b/xpfe/components/extensions/src/nsExtensionManager.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/xpinstall/packager/packages-static-unix b/xpinstall/packager/packages-static-unix index 97d51cbb2d4..bbc0f0e1b73 100644 --- a/xpinstall/packager/packages-static-unix +++ b/xpinstall/packager/packages-static-unix @@ -191,6 +191,8 @@ bin/components/filepicker.xpt bin/components/mozldap.xpt bin/components/typeaheadfind.xpt bin/components/nsCloseAllWindows.js +bin/components/extensions.xpt +bin/components/nsExtensionManager.js bin/chrome/help.jar bin/chrome/toolkit.jar bin/chrome/comm.jar diff --git a/xpinstall/packager/packages-static-win b/xpinstall/packager/packages-static-win index 596e84bbc4d..e0bb97aef6e 100644 --- a/xpinstall/packager/packages-static-win +++ b/xpinstall/packager/packages-static-win @@ -203,6 +203,8 @@ bin\components\progressDlg.xpt bin\components\nsDownloadProgressListener.js bin\components\typeaheadfind.xpt bin\components\nsCloseAllWindows.js +bin\components\extensions.xpt +bin\components\nsExtensionManager.js ; webservices bin\components\websrvcs.dll diff --git a/xpinstall/packager/packages-unix b/xpinstall/packager/packages-unix index 1d162e7d818..826d71cb6ab 100644 --- a/xpinstall/packager/packages-unix +++ b/xpinstall/packager/packages-unix @@ -249,6 +249,8 @@ bin/components/libuniversalchardet.so bin/components/typeaheadfind.xpt bin/components/libtypeaheadfind.so bin/components/nsCloseAllWindows.js +bin/components/extensions.xpt +bin/components/nsExtensionManager.js ; NegotiateAuth bin/components/libnegotiateauth.so diff --git a/xpinstall/packager/packages-win b/xpinstall/packager/packages-win index 08e1fd4e202..4eec98566ed 100644 --- a/xpinstall/packager/packages-win +++ b/xpinstall/packager/packages-win @@ -156,6 +156,8 @@ bin\components\typeaheadfind.xpt bin\components\typeaheadfind.dll bin\components\nsAxSecurityPolicy.js bin\components\nsCloseAllWindows.js +bin\components\extensions.xpt +bin\components\nsExtensionManager.js ; NegotiateAuth bin\components\negotiateauth.dll diff --git a/xpinstall/public/Makefile.in b/xpinstall/public/Makefile.in index d854e8216b3..8bbce2e4c6c 100644 --- a/xpinstall/public/Makefile.in +++ b/xpinstall/public/Makefile.in @@ -52,6 +52,7 @@ XPIDLSRCS = \ nsIXPIDialogService.idl \ nsIXPIProgressDialog.idl \ nsIXPINotifier.idl \ + nsIXPInstallManager.idl \ nsPIXPIProxy.idl \ nsPIXPIStubHook.idl \ nsPICertNotification.idl \ diff --git a/xpinstall/public/nsIXPInstallManager.idl b/xpinstall/public/nsIXPInstallManager.idl new file mode 100644 index 00000000000..bdd6920165a --- /dev/null +++ b/xpinstall/public/nsIXPInstallManager.idl @@ -0,0 +1,60 @@ +/* ***** 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 Mozilla XPInstall. + * + * The Initial Developer of the Original Code is Ben Goodger. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Ben Goodger + * + * 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 nsIXPIProgressDialog; + +/** + * Interface to XPInstallManager - manages download and install operations. + * + * @status UNDER_REVIEW + */ +[scriptable, uuid(50941e6a-ecfd-481c-9725-d0695c7c538e)] +interface nsIXPInstallManager : nsISupports +{ + /** + * Initiates a download and install operation of the supplied URLs + * and sends notifications to the supplied listener. + * @param aURLs array of XPI urls to download and install + * @param aURLCount number of XPI urls in aURLs + * @param aListener a listener to receive status notifications + */ + void initManagerFromChrome([array, size_is(aURLCount)] in wstring aURLs, + in unsigned long aURLCount, + in nsIXPIProgressDialog aListener); +}; + diff --git a/xpinstall/public/nsSoftwareUpdateIIDs.h b/xpinstall/public/nsSoftwareUpdateIIDs.h index 5a29b34188d..e5e3a77d117 100644 --- a/xpinstall/public/nsSoftwareUpdateIIDs.h +++ b/xpinstall/public/nsSoftwareUpdateIIDs.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -73,6 +72,13 @@ {0xbc, 0xde, 0x00, 0x80, 0x5f, 0x0e, 0x13, 0x53} \ } +#define NS_XPInstallManager_CID \ +{ /* {6a4d4c1e-a74a-4320-8124-16233a0183d6} */ \ + 0x6a4d4c1e, \ + 0xa74a, \ + 0x4320, \ + { 0x81, 0x24, 0x16, 0x23, 0x3a, 0x1, 0x83, 0xd6} \ +} #endif /* nsSoftwareUpdateIIDs_h___ */ diff --git a/xpinstall/src/nsInstall.cpp b/xpinstall/src/nsInstall.cpp index fe8c93d8a97..abac724283f 100644 --- a/xpinstall/src/nsInstall.cpp +++ b/xpinstall/src/nsInstall.cpp @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -21,11 +20,11 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Daniel Veditz - * Douglas Turner - * Pierre Phaneuf - * Sean Su - * Samir Gehani + * Daniel Veditz + * Douglas Turner + * Pierre Phaneuf + * Sean Su + * Samir Gehani * * 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"), @@ -41,8 +40,6 @@ * * ***** END LICENSE BLOCK ***** */ - - #include "nscore.h" #include "nsIFactory.h" #include "nsISupports.h" @@ -160,7 +157,8 @@ nsInstallInfo::nsInstallInfo(PRUint32 aInstallType, nsIPrincipal* aPrincipal, PRUint32 flags, nsIXPIListener* aListener, - nsIXULChromeRegistry* aChromeRegistry) + nsIXULChromeRegistry* aChromeRegistry, + nsIExtensionManager* aExtensionManager) : mPrincipal(aPrincipal), mError(0), mType(aInstallType), @@ -169,7 +167,8 @@ nsInstallInfo::nsInstallInfo(PRUint32 aInstallType, mArgs(aArgs), mFile(aFile), mListener(aListener), - mChromeRegistry(aChromeRegistry) + mChromeRegistry(aChromeRegistry), + mExtensionManager(aExtensionManager) { MOZ_COUNT_CTOR(nsInstallInfo); } @@ -1163,7 +1162,7 @@ PRInt32 nsInstall::LoadResources(JSContext* cx, const nsString& aBaseName, jsval* aReturn) { *aReturn = JSVAL_NULL; - + if (SanityCheck() != nsInstall::SUCCESS) { return NS_OK; @@ -1620,7 +1619,7 @@ nsInstall::FileOpDirGetParent(nsInstallFolder& aTarget, nsInstallFolder** thePar { return NS_ERROR_OUT_OF_MEMORY; } - folder->Init(parent,EmptyString()); + folder->Init(parent, EmptyString()); *theParentFolder = folder; } else @@ -2675,10 +2674,10 @@ nsInstall::ExtractFileFromJar(const nsString& aJarfile, nsIFile* aSuggestedName, if (asd) decodeErr = asd->Decode(); - delete asd; - if (decodeErr != noErr) { + if (asd) + delete asd; return EXTRACTION_FAILED; } diff --git a/xpinstall/src/nsInstall.h b/xpinstall/src/nsInstall.h index 621a4f12ebf..f9e507ca965 100644 --- a/xpinstall/src/nsInstall.h +++ b/xpinstall/src/nsInstall.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -38,7 +37,6 @@ * * ***** END LICENSE BLOCK ***** */ - #ifndef __NS_INSTALL_H__ #define __NS_INSTALL_H__ @@ -72,9 +70,10 @@ #include "nsIEnumerator.h" #include "nsIZipReader.h" #include "nsIChromeRegistry.h" +#include "nsIExtensionManager.h" #include "nsIPrincipal.h" -#define XPINSTALL_BUNDLE_URL "chrome://communicator/locale/xpinstall/xpinstall.properties" +#define XPINSTALL_BUNDLE_URL "chrome://global/locale/xpinstall/xpinstall.properties" //file and directory name length maximums #ifdef XP_MAC @@ -96,7 +95,8 @@ class nsInstallInfo nsIPrincipal* mPrincipal, PRUint32 aFlags, nsIXPIListener* aListener, - nsIXULChromeRegistry* aChromeReg); + nsIXULChromeRegistry* aChromeReg, + nsIExtensionManager* aExtensionManager); virtual ~nsInstallInfo(); @@ -107,6 +107,7 @@ class nsInstallInfo PRUint32 GetType() { return mType; } nsIXPIListener* GetListener() { return mListener.get(); } nsIXULChromeRegistry* GetChromeRegistry() { return mChromeRegistry.get(); } + nsIExtensionManager* GetExtensionManager(){ return mExtensionManager.get(); } nsCOMPtr mPrincipal; @@ -122,6 +123,7 @@ class nsInstallInfo nsCOMPtr mFile; nsCOMPtr mListener; nsCOMPtr mChromeRegistry; + nsCOMPtr mExtensionManager; }; #if defined(XP_WIN) || defined(XP_OS2) diff --git a/xpinstall/src/nsInstallTrigger.cpp b/xpinstall/src/nsInstallTrigger.cpp index 14da97bf434..170af0f3414 100644 --- a/xpinstall/src/nsInstallTrigger.cpp +++ b/xpinstall/src/nsInstallTrigger.cpp @@ -1,4 +1,3 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,7 +11,8 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla Communicator client code. + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. @@ -35,6 +35,7 @@ * * ***** END LICENSE BLOCK ***** */ + #include "nsSoftwareUpdate.h" #include "nsXPInstallManager.h" #include "nsInstallTrigger.h" @@ -56,6 +57,7 @@ #include "nsIDOMDocument.h" #include "nsIDocument.h" #include "nsIPrincipal.h" +#include "nsIObserverService.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" @@ -152,16 +154,25 @@ nsInstallTrigger::HandleContent(const char * aContentType, nsCOMPtr referringURI; nsCOMPtr channelprops(do_QueryInterface(channel)); - if (channelprops && - NS_SUCCEEDED(channelprops->Has(kReferrerProperty, &useReferrer)) && - useReferrer) + if (channelprops) { - // channel may have the property but set to null. In that case we know - // it was a typed URL or bookmark and can bypass site whitelisting, as - // opposed to not knowing the origin and going with the fallback plan. - channelprops->Get(kReferrerProperty, - NS_GET_IID(nsIURI), - getter_AddRefs(referringURI)); + // Get the referrer from the channel properties if we can (not all + // channels support our internal-referrer property). + // + // It's possible docshell explicitly set a null referrer in the case + // of typed, pasted, or bookmarked URLs and the like. In this null + // referrer case we get NS_ERROR_NO_INTERFACE rather than the usual + // NS_ERROR_FAILURE that indicates the property was not set at all. + // + // A null referrer is automatically whitelisted as an explicit user + // action (though they'll still get the confirmation dialog). For a + // missing referrer we go to our fall-back plan of using the XPI + // location for whitelisting purposes. + rv = channelprops->Get(kReferrerProperty, + NS_GET_IID(nsIURI), + getter_AddRefs(referringURI)); + if (NS_SUCCEEDED(rv) || rv == NS_ERROR_NO_INTERFACE) + useReferrer = PR_TRUE; } // Cancel the current request. nsXPInstallManager restarts the download @@ -170,7 +181,7 @@ nsInstallTrigger::HandleContent(const char * aContentType, // Get the global object of the target window for StartSoftwareUpdate - nsIScriptGlobalObject* globalObject = nsnull; + nsIScriptGlobalObject* globalObject; nsCOMPtr globalObjectOwner = do_QueryInterface(aWindowContext); if ( globalObjectOwner ) @@ -244,10 +255,15 @@ nsInstallTrigger::HandleContent(const char * aContentType, } else { - // TODO: fire event signaling blocked Install attempt + nsCOMPtr os(do_GetService("@mozilla.org/observer-service;1")); + if (os) { + os->NotifyObservers(globalObject->GetDocShell(), + "xpinstall-install-blocked", + NS_LITERAL_STRING("install-chrome").get()); + } rv = NS_ERROR_ABORT; } - + return rv; } @@ -394,7 +410,6 @@ nsInstallTrigger::UpdateEnabled(nsIScriptGlobalObject* aGlobalObject, PRBool aUs } - NS_IMETHODIMP nsInstallTrigger::Install(nsIScriptGlobalObject* aGlobalObject, nsXPITriggerInfo* aTrigger, PRBool* aReturn) { diff --git a/xpinstall/src/nsSoftwareUpdate.cpp b/xpinstall/src/nsSoftwareUpdate.cpp index 50aefbe0613..65fb66aef63 100644 --- a/xpinstall/src/nsSoftwareUpdate.cpp +++ b/xpinstall/src/nsSoftwareUpdate.cpp @@ -1,6 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** +/* ***** 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 @@ -13,7 +11,8 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla Communicator client code. + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. @@ -21,7 +20,6 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Pierre Phaneuf * * 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"), @@ -37,7 +35,6 @@ * * ***** END LICENSE BLOCK ***** */ - #include "nscore.h" #include "nsIGenericFactory.h" #include "nsIFactory.h" @@ -67,6 +64,7 @@ #include "nsInstallVersion.h" #include "ScheduledTasks.h" #include "InstallCleanupDefines.h" +#include "nsXPInstallManager.h" #include "nsTopProgressNotifier.h" #include "nsLoggingProgressNotifier.h" @@ -319,15 +317,24 @@ nsSoftwareUpdate::InstallJar( nsIFile* aLocalFile, nsresult rv; nsIXULChromeRegistry* chromeRegistry = nsnull; NS_WITH_ALWAYS_PROXIED_SERVICE( nsIXULChromeRegistry, - tmpReg, + tmpRegCR, NS_CHROMEREGISTRY_CONTRACTID, NS_UI_THREAD_EVENTQ, &rv); if (NS_SUCCEEDED(rv)) - chromeRegistry = tmpReg; + chromeRegistry = tmpRegCR; + + + NS_WITH_ALWAYS_PROXIED_SERVICE( nsIExtensionManager, + extensionManager, + "@mozilla.org/extensions/manager;1", + NS_UI_THREAD_EVENTQ, &rv); + if (NS_FAILED(rv)) + extensionManager = nsnull; // we want to call this with or without a chrome registry nsInstallInfo *info = new nsInstallInfo( 0, aLocalFile, aURL, aArguments, aPrincipal, - flags, aListener, chromeRegistry ); + flags, aListener, chromeRegistry, + extensionManager); if (!info) return NS_ERROR_OUT_OF_MEMORY; @@ -357,6 +364,13 @@ nsSoftwareUpdate::InstallChrome( PRUint32 aType, if (NS_FAILED(rv)) return rv; + NS_WITH_ALWAYS_PROXIED_SERVICE( nsIExtensionManager, + extensionManager, + "@mozilla.org/extensions/manager;1", + NS_UI_THREAD_EVENTQ, &rv); + if (NS_FAILED(rv)) + return rv; + nsInstallInfo *info = new nsInstallInfo( aType, aFile, URL, @@ -364,7 +378,8 @@ nsSoftwareUpdate::InstallChrome( PRUint32 aType, nsnull, (PRUint32)aSelect, aListener, - chromeRegistry); + chromeRegistry, + extensionManager); if (!info) return NS_ERROR_OUT_OF_MEMORY; @@ -510,6 +525,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSoftwareUpdate, nsSoftwareUpdate::GetInstance) NS_GENERIC_FACTORY_CONSTRUCTOR(nsInstallTrigger) NS_GENERIC_FACTORY_CONSTRUCTOR(nsInstallVersion) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPInstallManager) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSoftwareUpdateNameSet) //---------------------------------------------------------------------- @@ -583,6 +599,12 @@ static const nsModuleComponentInfo components[] = NS_SOFTWAREUPDATENAMESET_CID, NS_SOFTWAREUPDATENAMESET_CONTRACTID, nsSoftwareUpdateNameSetConstructor + }, + + { "XPInstallManager Component", + NS_XPInstallManager_CID, + NS_XPINSTALLMANAGERCOMPONENT_CONTRACTID, + nsXPInstallManagerConstructor } }; diff --git a/xpinstall/src/nsSoftwareUpdateRun.cpp b/xpinstall/src/nsSoftwareUpdateRun.cpp index 04317fc233b..5e9b9cad433 100644 --- a/xpinstall/src/nsSoftwareUpdateRun.cpp +++ b/xpinstall/src/nsSoftwareUpdateRun.cpp @@ -71,6 +71,8 @@ #include "nsIJAR.h" #include "nsIPrincipal.h" +#include "nsIExtensionManager.h" + #ifndef MOZ_XUL_APP #include "nsIChromeRegistrySea.h" #endif @@ -89,6 +91,8 @@ extern nsresult InitInstallTriggerGlobalClass(JSContext *jscontext, JSObject *gl // Defined in this file: PR_STATIC_CALLBACK(void) XPInstallErrorReporter(JSContext *cx, const char *message, JSErrorReport *report); static PRInt32 GetInstallScriptFromJarfile(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrincipal, char** scriptBuffer, PRUint32 *scriptLength); +static PRInt32 CanInstallFromExtensionManifest(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrincipal); + static nsresult SetupInstallContext(nsIZipReader* hZip, nsIFile* jarFile, const PRUnichar* url, const PRUnichar* args, PRUint32 flags, nsIXULChromeRegistry* reg, JSRuntime *jsRT, JSContext **jsCX, JSObject **jsGlob); @@ -242,6 +246,51 @@ XPInstallErrorReporter(JSContext *cx, const char *message, JSErrorReport *report +/////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : CanInstallFromExtensionManifest +// Description : Returns a stream to an extension manifest file from a passed jar file. +// Return type : PRInt32 +// Argument : nsIZipReader* hZip - the zip reader +// Argument : nsIFile* jarFile - the .xpi file +// Argument : nsIPrincipal* aPrincipal - a principal, if any, displayed to the user +// regarding the cert used to sign this install +/////////////////////////////////////////////////////////////////////////////////////////////// + +static PRInt32 +CanInstallFromExtensionManifest(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrincipal) +{ + PRInt32 result = NS_OK; + + nsIFile* jFile; + nsresult rv =jarFile->Clone(&jFile); + if (NS_SUCCEEDED(rv)) + rv = hZip->Init(jFile); + + if (NS_FAILED(rv)) + return nsInstall::CANT_READ_ARCHIVE; + + rv = hZip->Open(); + if (NS_FAILED(rv)) + return nsInstall::CANT_READ_ARCHIVE; + + // CRC check the integrity of all items in this archive + rv = hZip->Test(nsnull); + if (NS_FAILED(rv)) + { + NS_ASSERTION(0, "CRC check of archive failed!"); + return nsInstall::CANT_READ_ARCHIVE; + } + + rv = VerifySigning(hZip, aPrincipal); + if (NS_FAILED(rv)) + { + NS_ASSERTION(0, "Signing check of archive failed!"); + return nsInstall::INVALID_SIGNATURE; + } + + // Verify that install.rdf exists + return hZip->Test("install.rdf"); +} /////////////////////////////////////////////////////////////////////////////////////////////// @@ -478,94 +527,110 @@ extern "C" void RunInstallOnThread(void *data) if (NS_SUCCEEDED(rv)) { - finalStatus = GetInstallScriptFromJarfile( hZip, - jarpath, - installInfo->mPrincipal, - &scriptBuffer, - &scriptLength); - - if ( finalStatus == NS_OK && scriptBuffer ) + PRBool installed = PR_FALSE; + finalStatus = CanInstallFromExtensionManifest( hZip, + jarpath, + installInfo->mPrincipal); + if (NS_SUCCEEDED(finalStatus)) { - PRBool ownRuntime = PR_FALSE; - - nsCOMPtr rtsvc = - do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv); - if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt))) + nsIExtensionManager* em = installInfo->GetExtensionManager(); + if (em) { - // service not available (wizard context?) - // create our own runtime - ownRuntime = PR_TRUE; - rt = JS_Init(4L * 1024L * 1024L); + rv = em->InstallExtension(jarpath, nsIExtensionManager::FLAG_INSTALL_PROFILE); + if (NS_SUCCEEDED(rv)) + installed = PR_TRUE; } - - rv = SetupInstallContext( hZip, jarpath, - installInfo->GetURL(), - installInfo->GetArguments(), - installInfo->GetFlags(), - installInfo->GetChromeRegistry(), - rt, &cx, &glob); - - if (NS_SUCCEEDED(rv)) + } + + if (!installed) + { + finalStatus = GetInstallScriptFromJarfile( hZip, + jarpath, + installInfo->mPrincipal, + &scriptBuffer, + &scriptLength); + if ( finalStatus == NS_OK && scriptBuffer ) { - // Go ahead and run!! - jsval rval; - jsval installedFiles; - JS_BeginRequest(cx); //Increment JS thread counter associated - //with this context - PRBool ok = JS_EvaluateScript( cx, - glob, - scriptBuffer, - scriptLength, - nsnull, - 0, - &rval); + PRBool ownRuntime = PR_FALSE; - - if(!ok) + nsCOMPtr rtsvc = + do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv); + if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt))) { - // problem compiling or running script -- a true SCRIPT_ERROR - if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) && - JSVAL_TO_BOOLEAN(installedFiles)) - { - nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob); - a->InternalAbort(nsInstall::SCRIPT_ERROR); - } + // service not available (wizard context?) + // create our own runtime + ownRuntime = PR_TRUE; + rt = JS_Init(4L * 1024L * 1024L); + } - finalStatus = nsInstall::SCRIPT_ERROR; + rv = SetupInstallContext( hZip, jarpath, + installInfo->GetURL(), + installInfo->GetArguments(), + installInfo->GetFlags(), + installInfo->GetChromeRegistry(), + rt, &cx, &glob); + + if (NS_SUCCEEDED(rv)) + { + // Go ahead and run!! + jsval rval; + jsval installedFiles; + JS_BeginRequest(cx); //Increment JS thread counter associated + //with this context + PRBool ok = JS_EvaluateScript( cx, + glob, + scriptBuffer, + scriptLength, + nsnull, + 0, + &rval); + + + if(!ok) + { + // problem compiling or running script -- a true SCRIPT_ERROR + if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) && + JSVAL_TO_BOOLEAN(installedFiles)) + { + nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob); + a->InternalAbort(nsInstall::SCRIPT_ERROR); + } + + finalStatus = nsInstall::SCRIPT_ERROR; + } + else + { + // check to make sure the script sent back a status -- if + // not the install may have been syntactically correct but + // left the init/(perform|cancel) transaction open + + if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) && + JSVAL_TO_BOOLEAN(installedFiles)) + { + // install items remain in queue, must clean up! + nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob); + a->InternalAbort(nsInstall::MALFORMED_INSTALL); + } + + jsval sent; + if ( JS_GetProperty( cx, glob, "_finalStatus", &sent ) ) + finalStatus = JSVAL_TO_INT(sent); + else + finalStatus = nsInstall::UNEXPECTED_ERROR; + } + JS_EndRequest(cx); //Decrement JS thread counter + JS_DestroyContextMaybeGC(cx); } else { - // check to make sure the script sent back a status -- if - // not the install may have been syntactically correct but - // left the init/(perform|cancel) transaction open - - if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) && - JSVAL_TO_BOOLEAN(installedFiles)) - { - // install items remain in queue, must clean up! - nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob); - a->InternalAbort(nsInstall::MALFORMED_INSTALL); - } - - jsval sent; - if ( JS_GetProperty( cx, glob, "_finalStatus", &sent ) ) - finalStatus = JSVAL_TO_INT(sent); - else - finalStatus = nsInstall::UNEXPECTED_ERROR; + // couldn't initialize install context + finalStatus = nsInstall::UNEXPECTED_ERROR; } - JS_EndRequest(cx); //Decrement JS thread counter - JS_DestroyContextMaybeGC(cx); - } - else - { - // couldn't initialize install context - finalStatus = nsInstall::UNEXPECTED_ERROR; - } - // clean up Runtime if we created it ourselves - if ( ownRuntime ) - JS_DestroyRuntime(rt); - } + // clean up Runtime if we created it ourselves + if ( ownRuntime ) + JS_DestroyRuntime(rt); + } // force zip archive closed before other cleanup hZip = 0; } @@ -639,14 +704,48 @@ extern "C" void RunChromeInstallOnThread(void *data) if ( isSkin ) { - rv = reg->InstallSkin(spec.get(), PR_TRUE, PR_FALSE); + PRBool installed = PR_FALSE; + // Look for a theme manifest + + static NS_DEFINE_IID(kIZipReaderIID, NS_IZIPREADER_IID); + static NS_DEFINE_IID(kZipReaderCID, NS_ZIPREADER_CID); + nsresult rv; + nsCOMPtr hZip = do_CreateInstance(kZipReaderCID, &rv); + if (hZip) + rv = hZip->Init(info->GetFile()); + if (NS_SUCCEEDED(rv)) + { + hZip->Open(); + + nsIExtensionManager* em = info->GetExtensionManager(); + rv = hZip->Test("install.rdf"); + if (NS_SUCCEEDED(rv) && em) + { + rv = em->InstallTheme(info->GetFile(), nsIExtensionManager::FLAG_INSTALL_PROFILE); + if (NS_SUCCEEDED(rv)) + installed = PR_TRUE; + } + + hZip->Close(); + // Extension Manager copies the theme .jar file to + // a different location, so remove the temporary file. + info->GetFile()->Remove(PR_FALSE); + } + + // We either have an old-style theme with no theme.rdf + // manifest, OR we have a new style theme and InstallTheme + // returned an error (e.g. it's not implemented in Seamonkey, + // or something else went wrong) + if (!installed) + rv = reg->InstallSkin(spec.get(), PR_TRUE, PR_FALSE); + #ifndef MOZ_XUL_APP - if (NS_SUCCEEDED(rv) && selected && cr) - { - NS_ConvertUCS2toUTF8 utf8Args(info->GetArguments()); - cr->SelectSkin(utf8Args, PR_TRUE); - } + if (NS_SUCCEEDED(rv) && selected) + { + NS_ConvertUCS2toUTF8 utf8Args(info->GetArguments()); + rv = reg->SelectSkin(utf8Args, PR_TRUE); + } #endif } @@ -655,10 +754,10 @@ extern "C" void RunChromeInstallOnThread(void *data) rv = reg->InstallLocale(spec.get(), PR_TRUE); #ifndef MOZ_XUL_APP - if (NS_SUCCEEDED(rv) && selected && cr) + if (NS_SUCCEEDED(rv) && selected) { NS_ConvertUCS2toUTF8 utf8Args(info->GetArguments()); - cr->SelectLocale(utf8Args, PR_TRUE); + rv = cr->SelectLocale(utf8Args, PR_TRUE); } #endif } diff --git a/xpinstall/src/nsXPInstallManager.cpp b/xpinstall/src/nsXPInstallManager.cpp index afc3d429230..d56af702015 100644 --- a/xpinstall/src/nsXPInstallManager.cpp +++ b/xpinstall/src/nsXPInstallManager.cpp @@ -1,4 +1,3 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -17,12 +16,11 @@ * * The Initial Developer of the Original Code is * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-1999 + * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Daniel Veditz - * Pierre Phaneuf * * 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"), @@ -89,9 +87,12 @@ static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); #include "nsIEventQueueService.h" -#define PREF_XPINSTALL_CONFIRM_DLG "xpinstall.dialog.confirm" -#define PREF_XPINSTALL_STATUS_DLG "xpinstall.dialog.progress" -#define PREF_XPINSTALL_STATUS_DLG_TYPE "xpinstall.dialog.progress.type" +#define PREF_XPINSTALL_ENABLED "xpinstall.enabled" +#define PREF_XPINSTALL_CONFIRM_DLG "xpinstall.dialog.confirm" +#define PREF_XPINSTALL_STATUS_DLG_SKIN "xpinstall.dialog.progress.skin" +#define PREF_XPINSTALL_STATUS_DLG_CHROME "xpinstall.dialog.progress.chrome" +#define PREF_XPINSTALL_STATUS_DLG_TYPE_SKIN "xpinstall.dialog.progress.type.skin" +#define PREF_XPINSTALL_STATUS_DLG_TYPE_CHROME "xpinstall.dialog.progress.type.chrome" #define UPDATE_DLG(x) (((x) - mLastUpdate) > 250000) @@ -107,7 +108,7 @@ inline PRBool nsXPInstallManager::TimeToUpdate(PRTime now) nsXPInstallManager::nsXPInstallManager() : mTriggers(0), mItem(0), mNextItem(0), mNumJars(0), mChromeType(NOT_CHROME), mContentLength(0), mDialogOpen(PR_FALSE), mCancelled(PR_FALSE), - mSelectChrome(PR_TRUE), mNeedsShutdown(PR_FALSE) + mSelectChrome(PR_FALSE), mNeedsShutdown(PR_FALSE) { // we need to own ourself because we have a longer // lifetime than the scriptlet that created us. @@ -124,18 +125,15 @@ nsXPInstallManager::nsXPInstallManager() nsXPInstallManager::~nsXPInstallManager() { - nsCOMPtr os(do_GetService("@mozilla.org/observer-service;1")); - if (os) - os->RemoveObserver(this, XPI_PROGRESS_TOPIC); - if (mTriggers) delete mTriggers; } -NS_IMPL_THREADSAFE_ISUPPORTS8( nsXPInstallManager, +NS_IMPL_THREADSAFE_ISUPPORTS9( nsXPInstallManager, nsIXPIListener, nsIXPIDialogService, + nsIXPInstallManager, nsIObserver, nsIStreamListener, nsIProgressEventSink, @@ -143,6 +141,48 @@ NS_IMPL_THREADSAFE_ISUPPORTS8( nsXPInstallManager, nsPICertNotification, nsISupportsWeakReference) +NS_IMETHODIMP +nsXPInstallManager::InitManagerFromChrome(const PRUnichar **aURLs, PRUint32 aURLCount, + nsIXPIProgressDialog* aListener) +{ + // If Software Installation is not enabled, we don't want to proceed with + // update. + PRBool xpinstallEnabled = PR_TRUE; + nsCOMPtr pref(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (pref) + pref->GetBoolPref(PREF_XPINSTALL_ENABLED, &xpinstallEnabled); + + if (!xpinstallEnabled) + return NS_OK; + + mTriggers = new nsXPITriggerInfo(); + if (!mTriggers) + return NS_ERROR_OUT_OF_MEMORY; + + for (PRInt32 i = 0; i < aURLCount; ++i) + { + nsXPITriggerItem* item = new nsXPITriggerItem(0, aURLs[i], nsnull); + if (!item) + { + delete mTriggers; // nsXPITriggerInfo frees any alloc'ed nsXPITriggerItems + mTriggers = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + mTriggers->Add(item); + } + + nsresult rv; + mInstallSvc = do_GetService(nsSoftwareUpdate::GetCID(), &rv); + if (NS_FAILED(rv)) + { + delete mTriggers; + mTriggers = nsnull; + return rv; + } + + return Observe(aListener, XPI_PROGRESS_TOPIC, NS_LITERAL_STRING("open").get()); +} + NS_IMETHODIMP nsXPInstallManager::InitManager(nsIScriptGlobalObject* aGlobalObject, nsXPITriggerInfo* aTriggers, PRUint32 aChromeType) @@ -163,8 +203,12 @@ nsXPInstallManager::InitManager(nsIScriptGlobalObject* aGlobalObject, nsXPITrigg mParentWindow = do_QueryInterface(aGlobalObject); // Don't launch installs while page is still loading + PRBool isPageLoading = PR_FALSE; nsCOMPtr piWindow = do_QueryInterface(mParentWindow); - if (piWindow && piWindow->IsLoadingOrRunningTimeout()) + if (piWindow) + isPageLoading = piWindow->IsLoadingOrRunningTimeout(); + + if (isPageLoading) rv = NS_ERROR_FAILURE; else { @@ -383,12 +427,10 @@ PRBool nsXPInstallManager::ConfirmChromeInstall(nsIDOMWindowInternal* aParentWin nsCOMPtr dlgService(do_GetService("@mozilla.org/embedcomp/prompt-service;1")); if (dlgService) { - dlgService->ConfirmCheck( + dlgService->Confirm( aParentWindow, nsnull, confirmText, - applyNowText, - &mSelectChrome, &bInstall ); } @@ -431,12 +473,16 @@ nsXPInstallManager::OpenProgressDialog(const PRUnichar **aPackageList, PRUint32 char *statusDialogURL, *statusDialogType; nsCOMPtr pref(do_GetService(NS_PREFSERVICE_CONTRACTID)); if (pref) { - rv = pref->GetCharPref(PREF_XPINSTALL_STATUS_DLG, &statusDialogURL); + const char* statusDlg = mChromeType == CHROME_SKIN ? PREF_XPINSTALL_STATUS_DLG_SKIN + : PREF_XPINSTALL_STATUS_DLG_CHROME; + rv = pref->GetCharPref(statusDlg, &statusDialogURL); NS_ASSERTION(NS_SUCCEEDED(rv), "Can't invoke XPInstall FE without a FE URL! Set xpinstall.dialog.status"); if (NS_FAILED(rv)) return rv; - rv = pref->GetCharPref(PREF_XPINSTALL_STATUS_DLG_TYPE, &statusDialogType); + const char* statusType = mChromeType == CHROME_SKIN ? PREF_XPINSTALL_STATUS_DLG_TYPE_SKIN + : PREF_XPINSTALL_STATUS_DLG_TYPE_CHROME; + rv = pref->GetCharPref(statusType, &statusDialogType); nsAutoString type; type.AssignWithConversion(statusDialogType); if (NS_SUCCEEDED(rv) && !type.IsEmpty()) { @@ -458,7 +504,7 @@ nsXPInstallManager::OpenProgressDialog(const PRUnichar **aPackageList, PRUint32 rv = wwatch->OpenWindow(0, statusDialogURL, "_blank", - "chrome,centerscreen,titlebar,resizable", + "chrome,centerscreen,titlebar,dialog=no,resizable", params, getter_AddRefs(newWindow)); } @@ -742,6 +788,10 @@ void nsXPInstallManager::Shutdown() } } + nsCOMPtr os(do_GetService("@mozilla.org/observer-service;1")); + if (os) + os->RemoveObserver(this, XPI_PROGRESS_TOPIC); + NS_RELEASE_THIS(); } } @@ -749,9 +799,8 @@ void nsXPInstallManager::Shutdown() NS_IMETHODIMP nsXPInstallManager::LoadParams(PRUint32 aCount, const PRUnichar** aPackageList, nsIDialogParamBlock** aParams) { - nsIDialogParamBlock* paramBlock; - nsresult rv = CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, ¶mBlock); - + nsresult rv; + nsCOMPtr paramBlock = do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { // set OK and Cancel buttons diff --git a/xpinstall/src/nsXPInstallManager.h b/xpinstall/src/nsXPInstallManager.h index 36419617a25..be771710350 100644 --- a/xpinstall/src/nsXPInstallManager.h +++ b/xpinstall/src/nsXPInstallManager.h @@ -1,4 +1,3 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -17,7 +16,7 @@ * * The Initial Developer of the Original Code is * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-1999 + * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -50,6 +49,7 @@ #include "nsIInputStream.h" #include "nsIStreamListener.h" #include "nsIXPINotifier.h" +#include "nsIXPInstallManager.h" #include "nsIXPIDialogService.h" #include "nsXPITriggerInfo.h" #include "nsIXPIProgressDialog.h" @@ -72,10 +72,12 @@ #include "nsWeakReference.h" #define NS_XPIDIALOGSERVICE_CONTRACTID "@mozilla.org/embedui/xpinstall-dialog-service;1" +#define NS_XPINSTALLMANAGERCOMPONENT_CONTRACTID "@mozilla.org/xpinstall/install-manager;1" #define XPI_PROGRESS_TOPIC "xpinstall-progress" class nsXPInstallManager : public nsIXPIListener, public nsIXPIDialogService, + public nsIXPInstallManager, public nsIObserver, public nsIStreamListener, public nsIProgressEventSink, @@ -90,6 +92,7 @@ class nsXPInstallManager : public nsIXPIListener, NS_DECL_ISUPPORTS NS_DECL_NSIXPILISTENER NS_DECL_NSIXPIDIALOGSERVICE + NS_DECL_NSIXPINSTALLMANAGER NS_DECL_NSIOBSERVER NS_DECL_NSISTREAMLISTENER NS_DECL_NSIPROGRESSEVENTSINK