installationservices/swinstallationfw/source/siftransportrequest.cpp
branchRCL_3
changeset 25 7333d7932ef7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swinstallationfw/source/siftransportrequest.cpp	Tue Aug 31 15:21:33 2010 +0300
@@ -0,0 +1,279 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* Implements an AsyncRequest object for the SIF Transport library
+*
+*/
+
+
+#include <e32base.h>
+#include <e32std.h>
+#include <apgcli.h>
+#include <scs/ipcstream.h>
+#include <scs/nullstream.h>
+#include <scs/cleanuputils.h>
+#include <usif/usiferror.h>
+#include "usiflog.h"
+#include "siftransportserver.h"
+#include "siftransportcommon.h"
+
+using namespace Usif;
+
+void CSifTransportRequest::CreateAndExecuteL(TInt aFunction, CSifTransportSession* aSession, TransportTaskFactory::GenerateTask aTaskFactory, const RMessage2& aMessage)
+	{
+	DEBUG_PRINTF2(_L8("CSifTransportRequest::CreateAndExecuteL for aFunction = %d\n"),aFunction);
+		
+	CSifTransportRequest* self = new (ELeave) CSifTransportRequest(aFunction, aSession, aMessage);
+	CleanupStack::PushL(self);
+	
+	// Validate the file handle adoption.
+	TInt err = self->AdoptFileHandle(aFunction, aMessage);
+	if (err != KErrNone)
+		{
+		DEBUG_PRINTF2(_L8("Failed to adopt a file handle from RMessage2, error = %d\n"),err);
+		aMessage.Panic(KSifTransportServerRequestError, err);
+		User::Leave(err);
+		}
+		
+	self->PrepareParamsL();
+	self->SetupRequestL(aTaskFactory);
+	self->TransferToScsFrameworkL();
+	CleanupStack::Pop(self);
+	self->SetActive();
+	self->LaunchTask();
+	}
+
+// Read file handle from aMessage for all request by file handle.
+TInt CSifTransportRequest::AdoptFileHandle(TInt aFunction, const RMessage2& aMessage)
+	{	
+	if (aFunction & EFileHandleInIpc)
+		{
+		 return (iFile.AdoptFromClient(aMessage, 0, 1));
+		}
+	return KErrNone;
+	}
+
+CSifTransportRequest::CSifTransportRequest(TInt aFunction, CSifTransportSession* aSession, const RMessage2& aMessage)
+	:	CAsyncRequest(aSession, 0, aMessage), iFunction(aFunction), iSecurityContext(aMessage)
+	// iFile and iSecurityContext above cannot be a local variable because we pass it to SIF plug-ins during asynchronous calls.
+	// Hence, their lifetime must be guaranteed.
+	{
+	if (iFunction & EInstall)
+		{
+		iComponentId = EInvalidComponentId;
+		}
+
+	// Read component id from aMessage.
+	if (aFunction & EComponentIdInIpc)
+		{
+		iComponentId = aMessage.Int0();
+		}
+	}
+
+CSifTransportRequest::~CSifTransportRequest()
+	{
+	DEBUG_PRINTF2(_L8("CSifRequest::~CSifRequest() for aFunction = %d\n"),iFunction);
+
+	Cancel();
+	
+	if (iParams.iFileHandle != NULL)
+		{
+		iParams.iFileHandle->Close();
+		}
+
+	delete iParams.iFileName;
+	delete iParams.iComponentInfo;
+	delete iParams.iCustomArguments;
+	delete iParams.iCustomResults;
+	delete iTask;
+	}
+
+void CSifTransportRequest::PrepareParamsL()
+	{
+	DEBUG_PRINTF2(_L8("CSifRequest::PrepareParamsL() for aFunction = %d\n"),iFunction);
+
+	// Make sure that the buffers for opaque containers are not allocated
+	ASSERT(iParams.iComponentInfo == NULL);
+	ASSERT(iParams.iCustomArguments == NULL);
+	ASSERT(iParams.iCustomResults == NULL);
+
+	// Read file name from iMessagePtr2
+	if (iFunction & EFileNameInIpc)
+		{
+		// iFileName below cannot be a local variable because we pass it to installation
+		// requests during asynchronous calls. Hence, the lifetime of it must be guaranteed.
+		HBufC* fileName = HBufC::NewL(KMaxFileName);
+		iParams.iFileName = fileName;
+		TPtr bufFileName(fileName->Des());
+		iMessagePtr2.ReadL(0, bufFileName);
+		}
+
+	// Create component info
+	if (iFunction & EComponentInfoInIpc)
+		{
+		iParams.iComponentInfo = CComponentInfo::NewL();
+		}
+
+	// Create containers for custom params
+	if (iFunction & EOpaqueDataToPlugin)
+		{
+		// We have to also create these containers for asynchronous requests
+		// without opaque params. This is because a request API may not
+		// provide methods without opaque params in order to keep it small.
+		iParams.iCustomArguments = COpaqueNamedParams::NewL();
+		iParams.iCustomResults = COpaqueNamedParams::NewL();
+		}
+
+	// Read custom arguments from iMessagePtr2
+	if ((iFunction & EOpaqueDataInIpc) && (iFunction & EOpaqueDataToPlugin))
+		{
+		RIpcReadStream ipcrstream;
+		ipcrstream.Open(iMessagePtr2, 2);
+		CleanupClosePushL(ipcrstream);
+		ipcrstream >> const_cast<COpaqueNamedParams&>(*iParams.iCustomArguments);
+		CleanupStack::PopAndDestroy(&ipcrstream);
+		}
+	}
+
+void CSifTransportRequest::SetupRequestL(TransportTaskFactory::GenerateTask aTaskFactory)
+	{
+	DEBUG_PRINTF2(_L8("CSifTransportRequest::SetupInstallerRequestL() for aFunction = %d\n"),iFunction);
+
+	iParams.iSecurityContext = &iSecurityContext;
+	iParams.iRequestStatus = &iStatus;
+
+	// Instantiate an appropriate SIF Transport Task using aTaskFactory
+	switch (iFunction)
+		{
+		case EGetComponentInfoByFileName:
+		case EGetComponentInfoByFileHandle:
+			{
+			if (iParams.iFileName == NULL)
+				{
+				iParams.iFileHandle = &iFile;
+				}
+
+			iTask = aTaskFactory(TransportTaskFactory::EGetComponentInfo, iParams);
+			break;
+			}
+
+		case EInstallByFileName:
+		case EInstallByFileHandle:
+		case EInstallByFileNameWithOpaqueData:
+		case EInstallByFileHandleWithOpaqueData:
+			{
+			if (iParams.iFileName == NULL)
+				{
+				iParams.iFileHandle = &iFile;
+				}
+
+			iTask = aTaskFactory(TransportTaskFactory::EInstall, iParams);
+			break;
+			}
+
+		case EUninstall:
+		case EUninstallWithOpaqueData:
+			{
+			iParams.iComponentId = iComponentId;
+			iTask = aTaskFactory(TransportTaskFactory::EUninstall, iParams);
+			break;
+			}
+
+		case EActivate:
+			{
+			iParams.iComponentId = iComponentId;
+
+			iTask = aTaskFactory(TransportTaskFactory::EActivate, iParams);
+			break;
+			}
+
+		case EDeactivate:
+			{
+			iParams.iComponentId = iComponentId;
+			iTask = aTaskFactory(TransportTaskFactory::EDeactivate, iParams);
+			break;
+			}
+
+		default:
+			ASSERT(0);
+		}
+	}
+
+void CSifTransportRequest::DoCancel()
+	{
+	DEBUG_PRINTF2(_L8("CSifTransportRequest::DoCancel() for aFunction = %d\n"),iFunction);
+	
+	ASSERT(iTask != NULL);
+
+	iTask->Cancel();
+	}
+
+void CSifTransportRequest::DoCleanup()
+	{
+	DEBUG_PRINTF2(_L8("CSifTransportRequest::DoCleanup() for aFunction = %d\n"),iFunction);
+	Cancel();
+	}
+
+void CSifTransportRequest::ProcessOpaqueResultsL()
+	{
+	// Write custom results to iMessagePtr2
+	RIpcWriteStream ipcwstream;
+	ipcwstream.Open(iMessagePtr2, 3);
+	CleanupClosePushL(ipcwstream);
+	ipcwstream << *iParams.iCustomResults;
+	CleanupStack::PopAndDestroy(&ipcwstream);
+	}
+
+void CSifTransportRequest::ProcessTaskResultsL()
+	{
+	if (iFunction & EComponentInfoInIpc)
+		{
+		// Write component info to iMessagePtr2
+		RIpcWriteStream ipcwstream;
+		ipcwstream.Open(iMessagePtr2, 2);
+		CleanupClosePushL(ipcwstream);
+		ipcwstream << *iParams.iComponentInfo;
+		CleanupStack::PopAndDestroy(&ipcwstream);
+		}
+
+	if (iFunction & EOpaqueDataInIpc)
+		{
+		TRAPD(err, ProcessOpaqueResultsL());
+		if (err != KErrNone)
+			{
+			DEBUG_PRINTF3(_L8("CSifRequest::RunL() for aFunction = %d - received error %d while processing opaque results. The error is ignored, since the install operation has already completed"),iFunction, err);
+			}
+		}
+	}
+
+void CSifTransportRequest::RunL()
+	{
+	DEBUG_PRINTF2(_L8("CSifTransportRequest::RunL() for aFunction = %d\n"),iFunction);
+	
+	if (iTaskComplete)
+		{
+		ProcessTaskResultsL();
+		CAsyncRequest::RunL();
+		}
+	else
+		{
+		SetActive();
+		iTaskComplete = iTask->Execute();
+		}
+	}
+
+void CSifTransportRequest::LaunchTask()
+	{
+	iTaskComplete = iTask->Execute();
+	}