--- a/mtpfws/mtpfw/dataproviders/dputility/src/cmtpcopyobject.cpp Mon Mar 15 12:43:12 2010 +0200
+++ b/mtpfws/mtpfw/dataproviders/dputility/src/cmtpcopyobject.cpp Wed Mar 31 22:58:56 2010 +0300
@@ -23,6 +23,7 @@
#include <mtp/cmtptypearray.h>
#include <mtp/cmtptypestring.h>
+#include "cmtpfsentrycache.h"
#include "cmtpstoragemgr.h"
#include "cmtpcopyobject.h"
#include "mtpdppanic.h"
@@ -61,9 +62,17 @@
*/
EXPORT_C CMTPCopyObject::~CMTPCopyObject()
{
+ __FLOG(_L8("~CMTPCopyObject - Entry"));
+ Cancel();
+ iDpSingletons.Close();
+ iSingletons.Close();
+
+ delete iTimer;
delete iDest;
+ delete iNewFileName;
delete iFileMan;
- iSingletons.Close();
+
+ __FLOG(_L8("~CMTPCopyObject - Exit"));
__FLOG_CLOSE;
}
@@ -71,7 +80,8 @@
Standard c++ constructor
*/
CMTPCopyObject::CMTPCopyObject(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection) :
- CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPCopyObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPCopyObjectPolicy)
+ CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPCopyObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPCopyObjectPolicy),
+ iTimer(NULL)
{
__FLOG_OPEN(KMTPSubsystem, KComponent);
}
@@ -80,14 +90,33 @@
TMTPResponseCode CMTPCopyObject::CheckRequestL()
{
- __FLOG(_L8("CheckRequestL - Entry"));
+ __FLOG(_L8("CheckRequestL - Entry"));
TMTPResponseCode result = CMTPRequestProcessor::CheckRequestL();
if ( (EMTPRespCodeOK == result) && (!iSingletons.StorageMgr().IsReadWriteStorage(Request().Uint32(TMTPTypeRequest::ERequestParameter2))) )
{
result = EMTPRespCodeStoreReadOnly;
}
-
- __FLOG(_L8("CheckRequestL - Exit"));
+ if(result == EMTPRespCodeOK)
+ {
+ const TUint32 KHandle(Request().Uint32(TMTPTypeRequest::ERequestParameter1));
+ CMTPObjectMetaData* object(CMTPObjectMetaData::NewLC());
+ if(iFramework.ObjectMgr().ObjectL(KHandle, *object))
+ {
+ const TDesC& suid(object->DesC(CMTPObjectMetaData::ESuid));
+ iIsFolder = EFalse;
+ User::LeaveIfError(BaflUtils::IsFolder(iFramework.Fs(), suid, iIsFolder));
+ if(!iIsFolder)
+ {
+ if(iDpSingletons.CopyingBigFileCache().IsOnGoing())
+ {
+ __FLOG(_L8("CheckRequestL - A big file copying is ongoing, respond with access denied"));
+ result = EMTPRespCodeAccessDenied;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(object);
+ }
+ __FLOG(_L8("CheckRequestL - Exit"));
return result;
}
@@ -96,16 +125,20 @@
*/
void CMTPCopyObject::ServiceL()
{
+ __FLOG(_L8("ServiceL - Entry"));
TUint32 handle = KMTPHandleNone;
TMTPResponseCode responseCode = CopyObjectL(handle);
- if(responseCode == EMTPRespCodeOK)
+ if(responseCode != EMTPRespCodeOK)
{
+ __FLOG_VA((_L8("ServiceL, sending response with respond code %d"), responseCode));
+ SendResponseL(responseCode);
+ }
+ else if (iIsFolder)
+ {
+ __FLOG_VA((_L8("ServiceL, sending response with handle=%d, respond code OK"), handle));
SendResponseL(EMTPRespCodeOK, 1, &handle);
}
- else
- {
- SendResponseL(responseCode);
- }
+ __FLOG(_L8("ServiceL - Exit"));
}
@@ -113,9 +146,10 @@
Second phase constructor
*/
void CMTPCopyObject::ConstructL()
- {
+ {
iSingletons.OpenL();
- }
+ iDpSingletons.OpenL(iFramework);
+ }
/**
@@ -123,19 +157,28 @@
@param aNewFileName the new full filename after copy.
@return objectHandle of new copy of object.
*/
-TUint32 CMTPCopyObject::CopyFileL(const TDesC& aNewFileName)
+void CMTPCopyObject::CopyFileL(const TDesC& aNewFileName)
{
__FLOG(_L8("CopyFileL - Entry"));
+ delete iNewFileName;
+ iNewFileName = NULL;
+ iNewFileName = aNewFileName.AllocL(); // Store the new file name
const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
GetPreviousPropertiesL(suid);
- User::LeaveIfError(iFileMan->Copy(suid, *iDest));
- SetPreviousPropertiesL(aNewFileName);
- TUint32 handle = UpdateObjectInfoL(aNewFileName);
+ User::LeaveIfError(iFileMan->Copy(suid, *iDest, CFileMan::EOverWrite, iStatus));
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+
+ delete iTimer;
+ iTimer = NULL;
+ iTimer = CPeriodic::NewL(EPriorityStandard);
+ TTimeIntervalMicroSeconds32 KCopyObjectIntervalNone = 0;
+ iTimer->Start(TTimeIntervalMicroSeconds32(KCopyObjectTimeOut), KCopyObjectIntervalNone, TCallBack(CMTPCopyObject::OnTimeoutL, this));
__FLOG(_L8("CopyFileL - Exit"));
-
- return handle;
}
/**
@@ -183,11 +226,7 @@
const TDesC& suid(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
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())
{
@@ -213,9 +252,9 @@
iFileMan = NULL;
iFileMan = CFileMan::NewL(iFramework.Fs());
- if(!isFolder) // It is a file.
+ if(!iIsFolder) // It is a file.
{
- aNewHandle = CopyFileL(newObjectName);
+ CopyFileL(newObjectName);
}
else // It is a folder.
{
@@ -357,3 +396,122 @@
return handle;
}
+
+/**
+ Call back function, called when the timer expired for big file copying.
+ Send response to initiator and cache the target file entry info, which is used to send response
+ to getobjectproplist and getobjectinfo.
+*/
+TInt CMTPCopyObject::OnTimeoutL(TAny* aPtr)
+ {
+ CMTPCopyObject* copyObjectProcessor = static_cast<CMTPCopyObject*>(aPtr);
+ copyObjectProcessor->DoOnTimeoutL();
+ return KErrNone;
+ }
+
+void CMTPCopyObject::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 = KMTPHandleNone;
+ handle = UpdateObjectInfoL(*iNewFileName);
+ CMTPFSEntryCache& aCache = iDpSingletons.CopyingBigFileCache();
+
+ // 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_VA((_L8("UpdateFSEntryCache, sending response with handle=%d, respond code OK for a big file copy"), handle));
+ SendResponseL(EMTPRespCodeOK, 1, &handle);
+
+ __FLOG(_L8("DoOnTimeoutL - Exit"));
+ }
+
+/**
+ CMTPCopyObject::RunL
+*/
+void CMTPCopyObject::RunL()
+ {
+ __FLOG(_L8("RunL - Entry"));
+
+ User::LeaveIfError(iStatus.Int());
+ SetPreviousPropertiesL(*iNewFileName);
+ CMTPFSEntryCache& aCache = iDpSingletons.CopyingBigFileCache();
+ // Check to see if we are copying a big file
+ if(aCache.IsOnGoing())
+ {
+ __FLOG(_L8("RunL - Big file copy complete"));
+ aCache.SetOnGoing(EFalse);
+ aCache.SetTargetHandle(KMTPHandleNone);
+ }
+ else
+ {
+ //Cancel the timer
+ if(iTimer)
+ {
+ if (iTimer->IsActive())
+ {
+ iTimer->Cancel();
+ }
+ delete iTimer;
+ iTimer = NULL;
+ }
+
+ TUint32 handle = UpdateObjectInfoL(*iNewFileName);
+ __FLOG_VA((_L8("RunL, sending response with handle=%d, respond code OK for a normal file copy"), handle));
+ SendResponseL(EMTPRespCodeOK, 1, &handle);
+ }
+ __FLOG(_L8("RunL - Exit"));
+ }
+
+/**
+Override to handle the complete phase of copy object
+@return EFalse
+*/
+TBool CMTPCopyObject::DoHandleCompletingPhaseL()
+ {
+ CMTPRequestProcessor::DoHandleCompletingPhaseL();
+
+ CMTPFSEntryCache& aCache = iDpSingletons.CopyingBigFileCache();
+ if(aCache.IsOnGoing())
+ {
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+/**
+Override to match CopyObject 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 CMTPCopyObject::Match(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) const
+ {
+ __FLOG(_L8("Match - Entry"));
+ TBool result = EFalse;
+ TUint16 operationCode = aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode);
+ if ((operationCode == EMTPOpCodeCopyObject) && &iConnection == &aConnection)
+ {
+ result = ETrue;
+ }
+ __FLOG_VA((_L8("Match -- Exit with result = %d"), result));
+ return result;
+ }