Mozilla/mozilla/xpinstall/src/nsInstallTrigger.cpp
dougt%netscape.com 175245e2de Relanding Necko Changes.
Revising nsIChannel to allow for overlapped i/o. This consists of three parts:

1. Factoring nsIChannel into a protocol specific part, the nsIChannel, and a socket specific, the nsITransport.
2. Derive the nsIChannel from a nsIRequest.
2. Changes the notification system from necko and the URILoader to pass the nsIRequest interface instead of nsIChannel interface.

This goal stems from wanting to be able to have active AsyncRead and AsyncWrite operations on nsSocketTransport.
This is desired because it would greatly simplify the task of maintaining persistent/reusable socket connections
for FTP, HTTP, and Imap (and potentially other protocols). The problem with the existing nsIChannel interface is
that it does not allow one to selectively suspend just one of the read or write operations while keeping the other active.

r=darin@netscape.com
sr=rpotts@netscape.com


git-svn-id: svn://10.0.0.236/trunk@87587 18797224-902f-48f8-a5cc-f745e15eee43
2001-02-21 20:38:08 +00:00

392 lines
10 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsSoftwareUpdate.h"
#include "nsXPInstallManager.h"
#include "nsInstallTrigger.h"
#include "nsInstallVersion.h"
#include "nsIDOMInstallTriggerGlobal.h"
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIPref.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
#include "nsSpecialSystemDirectory.h"
#include "VerReg.h"
#include "nsIContentHandler.h"
#include "nsIChannel.h"
#include "nsIURI.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIInstallTrigger_IID, NS_IDOMINSTALLTRIGGERGLOBAL_IID);
static NS_DEFINE_IID(kIInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
static NS_DEFINE_IID(kPrefsIID, NS_IPREF_IID);
static NS_DEFINE_IID(kPrefsCID, NS_PREF_CID);
nsInstallTrigger::nsInstallTrigger()
{
mScriptObject = nsnull;
NS_INIT_ISUPPORTS();
}
nsInstallTrigger::~nsInstallTrigger()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS3 (nsInstallTrigger,
nsIScriptObjectOwner,
nsIDOMInstallTriggerGlobal,
nsIContentHandler);
NS_IMETHODIMP
nsInstallTrigger::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
nsresult res = NS_OK;
if (nsnull == mScriptObject)
{
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
res = NS_NewScriptInstallTriggerGlobal( aContext,
(nsISupports *)(nsIDOMInstallTriggerGlobal*)this,
(nsISupports *)global,
&mScriptObject);
NS_IF_RELEASE(global);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsInstallTrigger::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::HandleContent(const char * aContentType,
const char * aCommand,
const char * aWindowTarget,
nsISupports* aWindowContext,
nsIRequest* request)
{
nsresult rv = NS_OK;
if (!request) return NS_ERROR_NULL_POINTER;
if (nsCRT::strcasecmp(aContentType, "application/x-xpinstall") == 0) {
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
rv = aChannel->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (uri) {
char* spec;
uri->GetSpec(&spec);
if (!spec)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIScriptGlobalObjectOwner> globalObjectOwner = do_QueryInterface(aWindowContext);
if (globalObjectOwner)
{
nsCOMPtr<nsIScriptGlobalObject> globalObject;
globalObjectOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
if (globalObject)
{
PRBool value;
rv = StartSoftwareUpdate(globalObject, NS_ConvertASCIItoUCS2(spec), 0, &value);
nsMemory::Free(spec);
if (NS_SUCCEEDED(rv) && value)
return NS_OK;
}
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsInstallTrigger::UpdateEnabled(PRBool* aReturn)
{
nsIPref * prefs;
nsresult rv = nsServiceManager::GetService(kPrefsCID,
kPrefsIID,
(nsISupports**) &prefs);
if ( NS_SUCCEEDED(rv) )
{
rv = prefs->GetBoolPref( (const char*) XPINSTALL_ENABLE_PREF, aReturn);
if (NS_FAILED(rv))
{
*aReturn = PR_FALSE;
}
NS_RELEASE(prefs);
}
else
{
*aReturn = PR_FALSE; /* no prefs manager. set to false */
}
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::Install(nsIScriptGlobalObject* aGlobalObject, nsXPITriggerInfo* aTrigger, PRBool* aReturn)
{
NS_ASSERTION(aReturn, "Invalid pointer arg");
*aReturn = PR_FALSE;
PRBool enabled;
nsresult rv = UpdateEnabled(&enabled);
if (NS_FAILED(rv) || !enabled)
{
delete aTrigger;
return NS_OK;
}
nsXPInstallManager *mgr = new nsXPInstallManager();
if (mgr)
{
// The Install manager will delete itself when done
rv = mgr->InitManager( aGlobalObject, aTrigger, 0 );
if (NS_SUCCEEDED(rv))
*aReturn = PR_TRUE;
}
else
{
delete aTrigger;
rv = NS_ERROR_OUT_OF_MEMORY;
}
return rv;
}
NS_IMETHODIMP
nsInstallTrigger::InstallChrome(nsIScriptGlobalObject* aGlobalObject, PRUint32 aType, nsXPITriggerItem *aItem, PRBool* aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
NS_ENSURE_ARG_POINTER(aItem);
*aReturn = PR_FALSE;
// make sure we're allowing installs
PRBool enabled;
nsresult rv = UpdateEnabled(&enabled);
if (NS_FAILED(rv) || !enabled)
return NS_OK;
// The Install manager will delete itself when done, once we've called
// InitManager. Before then **WE** must delete it
nsXPInstallManager *mgr = new nsXPInstallManager();
if (mgr)
{
nsXPITriggerInfo* trigger = new nsXPITriggerInfo();
if ( trigger )
{
trigger->Add( aItem );
// The Install manager will delete itself when done
rv = mgr->InitManager( aGlobalObject, trigger, aType );
*aReturn = PR_TRUE;
}
else
{
rv = NS_ERROR_OUT_OF_MEMORY;
delete mgr;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::StartSoftwareUpdate(nsIScriptGlobalObject* aGlobalObject, const nsString& aURL, PRInt32 aFlags, PRBool* aReturn)
{
PRBool enabled;
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
*aReturn = PR_FALSE;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
// The Install manager will delete itself when done, once we've called
// InitManager. Before then **WE** must delete it
nsXPInstallManager *mgr = new nsXPInstallManager();
if (mgr)
{
nsXPITriggerInfo* trigger = new nsXPITriggerInfo();
if ( trigger )
{
nsXPITriggerItem* item = new nsXPITriggerItem(0,aURL.GetUnicode());
if (item)
{
trigger->Add( item );
// The Install manager will delete itself when done
rv = mgr->InitManager(aGlobalObject, trigger, 0 );
*aReturn = PR_TRUE;
}
else
{
rv = NS_ERROR_OUT_OF_MEMORY;
delete trigger;
delete mgr;
}
}
else
{
rv = NS_ERROR_OUT_OF_MEMORY;
delete mgr;
}
}
return rv;
}
NS_IMETHODIMP
nsInstallTrigger::CompareVersion(const nsString& aRegName, PRInt32 aMajor, PRInt32 aMinor, PRInt32 aRelease, PRInt32 aBuild, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aMajor, aMinor, aRelease, aBuild);
return CompareVersion(aRegName, &inVersion, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::CompareVersion(const nsString& aRegName, const nsString& aVersion, PRInt32* aReturn)
{
nsInstallVersion inVersion;
inVersion.Init(aVersion);
return CompareVersion(aRegName, &inVersion, aReturn);
}
NS_IMETHODIMP
nsInstallTrigger::CompareVersion(const nsString& aRegName, nsIDOMInstallVersion* aVersion, PRInt32* aReturn)
{
*aReturn = EQUAL; // assume failure.
PRBool enabled;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
VERSION cVersion;
NS_ConvertUCS2toUTF8 regName(aRegName);
REGERR status;
nsInstallVersion regNameVersion;
status = VR_GetVersion( regName, &cVersion );
/* if we got the version */
if ( status == REGERR_OK )
{
if ( VR_ValidateComponent( regName ) == REGERR_NOFILE )
{
regNameVersion.Init(0,0,0,0);
}
else
{
regNameVersion.Init(cVersion.major,
cVersion.minor,
cVersion.release,
cVersion.build);
}
}
else
regNameVersion.Init(0,0,0,0);
regNameVersion.CompareTo( aVersion, aReturn );
return NS_OK;
}
NS_IMETHODIMP
nsInstallTrigger::GetVersion(const nsString& component, nsString& version)
{
PRBool enabled;
UpdateEnabled(&enabled);
if (!enabled)
return NS_OK;
VERSION cVersion;
NS_ConvertUCS2toUTF8 regName(component);
REGERR status;
status = VR_GetVersion( regName, &cVersion );
version.Truncate();
/* if we got the version */
// XXX fix the right way after PR3 or RTM
// if ( status == REGERR_OK && VR_ValidateComponent( tempCString ) == REGERR_OK)
if ( status == REGERR_OK )
{
nsInstallVersion regNameVersion;
regNameVersion.Init(cVersion.major,
cVersion.minor,
cVersion.release,
cVersion.build);
regNameVersion.ToString(version);
}
return NS_OK;
}