mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp
branchRCL_3
changeset 19 ef55b168cedb
parent 14 60a94a45d437
child 32 f85613f12947
--- a/mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp	Wed Apr 14 16:49:36 2010 +0300
+++ b/mtpfws/mtpfw/dataproviders/dputility/src/cmtpmoveobject.cpp	Tue Apr 27 17:30:23 2010 +0300
@@ -23,6 +23,7 @@
 #include <mtp/cmtptypearray.h>
 #include <mtp/cmtptypestring.h>
 
+#include "cmtpfsentrycache.h"
 #include "cmtpstoragemgr.h"
 #include "cmtpmoveobject.h"
 #include "mtpdppanic.h"
@@ -61,12 +62,17 @@
 Destructor
 */	
 EXPORT_C CMTPMoveObject::~CMTPMoveObject()
-	{	
+	{
+	Cancel();
+	iDpSingletons.Close();
+	iSingletons.Close();
+	
+	delete iTimer;
+	delete iNewFileName;
 	delete iDest;
 	delete iFileMan;
 	delete iPathToMove;
-	delete iNewRootFolder;
-	iSingletons.Close();
+	delete iNewRootFolder;	
 	__FLOG_CLOSE;
 	}
 
@@ -75,7 +81,7 @@
 */	
 CMTPMoveObject::CMTPMoveObject(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) :
 	CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPMoveObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPMoveObjectPolicy),
-	iMoveObjectIndex(0)
+	iMoveObjectIndex(0), iTimer(NULL)
 	{
 	__FLOG_OPEN(KMTPSubsystem, KComponent);
 	}
@@ -104,6 +110,21 @@
 		result = EMTPRespCodeStoreReadOnly;
 		}
 	
+	if(result == EMTPRespCodeOK)
+		{
+		const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
+		iIsFolder = EFalse;
+		User::LeaveIfError(BaflUtils::IsFolder(iFramework.Fs(), suid, iIsFolder));
+		if(!iIsFolder)
+			{
+			if(iDpSingletons.MovingBigFileCache().IsOnGoing())
+				{
+				__FLOG(_L8("CheckRequestL - A big file moving is ongoing, respond with access denied"));
+				result = EMTPRespCodeAccessDenied;
+				}
+			}
+		}
+	
     __FLOG(_L8("CheckRequestL - Exit"));
 	return result;	
 	} 
@@ -112,7 +133,8 @@
 MoveObject request handler
 */		
 void CMTPMoveObject::ServiceL()
-	{	
+	{
+	__FLOG(_L8("ServiceL - Entry"));
 	TMTPResponseCode ret = EMTPRespCodeOK;
 	TRAPD(err, ret = MoveObjectL());
 	if (err != KErrNone)
@@ -123,6 +145,7 @@
 		{
 		SendResponseL(ret);
 		}
+	__FLOG(_L8("ServiceL - Exit"));
 	}
 
 /**
@@ -131,6 +154,7 @@
 void CMTPMoveObject::ConstructL()
     {
 	iSingletons.OpenL();
+	iDpSingletons.OpenL(iFramework);
     }
     
 
@@ -143,12 +167,38 @@
 	__FLOG(_L8("MoveFileL - Entry"));
 	const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
 	GetPreviousPropertiesL(suid);
-	User::LeaveIfError(iFileMan->Move(suid, *iDest));
-	SetPreviousPropertiesL(aNewFileName);
-	iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aNewFileName);
-	iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
-	iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle);
-	iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);
+	
+	if(iFramework.StorageMgr().DriveNumber(iObjectInfo->Uint(CMTPObjectMetaData::EStorageId)) ==
+			iFramework.StorageMgr().DriveNumber(iStorageId))
+		//Move file to the same storage
+		{
+		User::LeaveIfError(iFileMan->Move(suid, *iDest));
+		SetPreviousPropertiesL(aNewFileName);
+		iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aNewFileName);
+		iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
+		iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle);
+		iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);
+		SendResponseL(EMTPRespCodeOK);
+		}
+	else
+		//Move file between different storages
+		{
+		delete iNewFileName;
+		iNewFileName = NULL;
+		iNewFileName = aNewFileName.AllocL(); // Store the new file name
+		
+		User::LeaveIfError(iFileMan->Move(suid, *iDest, CFileMan::EOverWrite, iStatus));
+		if ( !IsActive() )
+		{  
+		SetActive();
+		}
+		
+		delete iTimer;
+		iTimer = NULL;
+		iTimer = CPeriodic::NewL(EPriorityStandard);
+		TTimeIntervalMicroSeconds32 KMoveObjectIntervalNone = 0;	
+		iTimer->Start(TTimeIntervalMicroSeconds32(KMoveObjectTimeOut), KMoveObjectIntervalNone, TCallBack(CMTPMoveObject::OnTimeoutL, this));		
+		}
 	__FLOG(_L8("MoveFileL - Exit"));
 	}
 
@@ -206,10 +256,7 @@
 	TParsePtrC fileNameParser(suid);
 	
 	// Check if the object is a folder or a file.
-	TBool isFolder = EFalse;
-	User::LeaveIfError(BaflUtils::IsFolder(iFramework.Fs(), suid, isFolder));	
-				
-	if(!isFolder)
+	if(!iIsFolder)
 		{
 		if((newObjectName.Length() + fileNameParser.NameAndExt().Length()) <= newObjectName.MaxLength())
 			{
@@ -239,10 +286,9 @@
 		iFileMan = NULL;
 		iFileMan = CFileMan::NewL(iFramework.Fs());
 		
-		if(!isFolder)
+		if(!iIsFolder)
 			{
 			MoveFileL(newObjectName);
-			SendResponseL(responseCode);
 			}
 		else
 			{		
@@ -347,7 +393,129 @@
 	__FLOG(_L8("SetPreviousPropertiesL - Exit"));
 	}
 
+/**
+ Call back function, called when the timer expired for big file moving.
+ Send response to initiator and cache the target file entry info, which is used to send response 
+ to getobjectproplist and getobjectinfo.
+*/
+TInt CMTPMoveObject::OnTimeoutL(TAny* aPtr)
+	{
+	CMTPMoveObject* moveObjectProcessor = static_cast<CMTPMoveObject*>(aPtr);
+	moveObjectProcessor->DoOnTimeoutL();
+	return KErrNone;
+	}
 
+void CMTPMoveObject::DoOnTimeoutL()
+	{
+	__FLOG(_L8("DoOnTimeoutL - Entry"));
+	
+	if (iTimer)
+		{
+		if (iTimer->IsActive())
+			{
+			iTimer->Cancel();
+			}
+		delete iTimer;
+		iTimer = NULL;
+		}
+	
+	const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
+	TEntry fileEntry;
+	User::LeaveIfError(iFramework.Fs().Entry(suid, fileEntry));
+	TUint32 handle = iObjectInfo->Uint(CMTPObjectMetaData::EHandle);
+	
+	iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, *iNewFileName);
+	iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
+	iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle);
+	iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);
+	
+	CMTPFSEntryCache& aCache = iDpSingletons.MovingBigFileCache();
+	
+	// Cache the target file entry info, which is used to send response to getobjectproplist and getobjectinfo
+	aCache.SetOnGoing(ETrue);
+	aCache.SetTargetHandle(handle);
+	aCache.SetFileEntry(fileEntry);	
+	
+	__FLOG(_L8("UpdateFSEntryCache, sending response with respond code OK for a big file move"));
+	SendResponseL(EMTPRespCodeOK);
+	
+	__FLOG(_L8("DoOnTimeoutL - Exit"));
+	}
 
+/**
+ CMTPMoveObject::RunL
+*/
+void CMTPMoveObject::RunL()
+	{
+	__FLOG(_L8("RunL - Entry"));
+	
+	User::LeaveIfError(iStatus.Int());
+	SetPreviousPropertiesL(*iNewFileName);
+	CMTPFSEntryCache& aCache = iDpSingletons.MovingBigFileCache();
+	// Check to see if we are moving a big file
+	if(aCache.IsOnGoing())
+		{
+		__FLOG(_L8("RunL - Big file move complete"));
+		aCache.SetOnGoing(EFalse);
+		aCache.SetTargetHandle(KMTPHandleNone);
+		}
+	else
+		{
+		//Cancel the timer
+		if(iTimer)
+			{
+			if(iTimer->IsActive())
+				{
+				iTimer->Cancel();
+				}
+			delete iTimer;
+			iTimer = NULL;
+			}
 
+		iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, *iNewFileName);
+		iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
+		iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle);
+		iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);
 
+		__FLOG(_L8("RunL, sending response with respond code OK for a normal file move"));
+		SendResponseL(EMTPRespCodeOK);
+		}
+	__FLOG(_L8("RunL - Exit"));
+	}
+
+/**
+Override to handle the complete phase of move object
+*/
+TBool CMTPMoveObject::DoHandleCompletingPhaseL()
+	{
+	CMTPRequestProcessor::DoHandleCompletingPhaseL();
+	
+	CMTPFSEntryCache& aCache = iDpSingletons.MovingBigFileCache();
+	if(aCache.IsOnGoing())
+		{
+		return EFalse;
+		}
+	else
+		{
+		return ETrue;
+		}
+	}
+
+/**
+Override to match MoveObject request
+@param aRequest    The request to match
+@param aConnection The connection from which the request comes
+@return ETrue if the processor can handle the request, otherwise EFalse
+*/        
+TBool CMTPMoveObject::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const
+	{
+	__FLOG(_L8("Match - Entry"));
+	TBool result = EFalse;
+	TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
+	if ((operationCode == EMTPOpCodeMoveObject) && &iConnection == &aConnection)
+	{
+	result = ETrue;
+	}    
+	__FLOG_VA((_L8("Match -- Exit with result = %d"), result));
+	return result;
+	}