installationservices/swinstallationfw/source/siftransportrequest.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:21:33 +0300
branchRCL_3
changeset 25 7333d7932ef7
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* 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();
	}