mtpdataproviders/mtpimagedp/src/cmtpimagedpmoveobject.cpp
changeset 0 d0791faffa3f
child 2 4843bb5893b6
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #include <f32file.h>
       
    22 #include <bautils.h>
       
    23 #include <pathinfo.h> // PathInfo
       
    24 #include <sysutil.h>
       
    25 
       
    26 #include <mtp/mmtpdataproviderframework.h>
       
    27 #include <mtp/mmtpobjectmgr.h>
       
    28 #include <mtp/mmtpstoragemgr.h>
       
    29 #include <mtp/cmtpobjectmetadata.h>
       
    30 #include <mtp/cmtptypearray.h>
       
    31 #include <mtp/cmtptypestring.h>
       
    32 
       
    33 #include "cmtpimagedpmoveobject.h"
       
    34 #include "mtpimagedppanic.h"
       
    35 #include "cmtpimagedpobjectpropertymgr.h"
       
    36 #include "mtpimagedputilits.h"
       
    37 #include "cmtpimagedpthumbnailcreator.h"
       
    38 #include "cmtpimagedp.h"
       
    39 
       
    40 __FLOG_STMT(_LIT8(KComponent,"MoveObject");)
       
    41 
       
    42 /**
       
    43 Verification data for the MoveObject request
       
    44 */    
       
    45 const TMTPRequestElementInfo KMTPMoveObjectPolicy[] = 
       
    46     {
       
    47         {TMTPTypeRequest::ERequestParameter2, EMTPElementTypeStorageId, EMTPElementAttrWrite, 0, 0, 0},
       
    48         {TMTPTypeRequest::ERequestParameter3, EMTPElementTypeObjectHandle, EMTPElementAttrDir | EMTPElementAttrWrite, 1, 0, 0}
       
    49     };
       
    50 
       
    51 /**
       
    52 Two-phase construction method
       
    53 @param aPlugin	The data provider plugin
       
    54 @param aFramework	The data provider framework
       
    55 @param aConnection	The connection from which the request comes
       
    56 @return a pointer to the created request processor object
       
    57 */     
       
    58 MMTPRequestProcessor* CMTPImageDpMoveObject::NewL(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection,CMTPImageDataProvider& aDataProvider)
       
    59     {
       
    60     CMTPImageDpMoveObject* self = new (ELeave) CMTPImageDpMoveObject(aFramework, aConnection,aDataProvider);
       
    61     CleanupStack::PushL(self);
       
    62     self->ConstructL();
       
    63     CleanupStack::Pop(self);
       
    64     return self;
       
    65     }
       
    66 
       
    67 /**
       
    68 Destructor
       
    69 */	
       
    70 CMTPImageDpMoveObject::~CMTPImageDpMoveObject()
       
    71     {
       
    72     __FLOG(_L8(">> CMTPImageDpMoveObject::~CMTPImageDpMoveObject")); 
       
    73     delete iDest;
       
    74     delete iFileMan;
       
    75     delete iObjectInfo;
       
    76     __FLOG(_L8("<< CMTPImageDpMoveObject::~CMTPImageDpMoveObject"));
       
    77     __FLOG_CLOSE;
       
    78     }
       
    79 
       
    80 /**
       
    81 Standard c++ constructor
       
    82 */	
       
    83 CMTPImageDpMoveObject::CMTPImageDpMoveObject(MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection,CMTPImageDataProvider& aDataProvider) :
       
    84     CMTPRequestProcessor(aFramework, aConnection, sizeof(KMTPMoveObjectPolicy)/sizeof(TMTPRequestElementInfo), KMTPMoveObjectPolicy),
       
    85     iDataProvider(aDataProvider)
       
    86     {
       
    87     __FLOG_OPEN(KMTPSubsystem, KComponent);
       
    88     }
       
    89 	
       
    90 /**
       
    91  Second phase constructor
       
    92 */
       
    93 void CMTPImageDpMoveObject::ConstructL()
       
    94     {
       
    95     __FLOG(_L8(">> CMTPImageDpMoveObject::ConstructL")); 
       
    96     iFileMan = CFileMan::NewL(iFramework.Fs());
       
    97     iObjectInfo = CMTPObjectMetaData::NewL();
       
    98     __FLOG(_L8("<< CMTPImageDpMoveObject::ConstructL")); 
       
    99     }
       
   100 
       
   101 TMTPResponseCode CMTPImageDpMoveObject::CheckRequestL()
       
   102     {
       
   103     __FLOG(_L8(">> CMTPImageDpCopyObject::CheckRequestL"));
       
   104     TMTPResponseCode responseCode = CMTPRequestProcessor::CheckRequestL();
       
   105     if (EMTPRespCodeOK == responseCode)
       
   106         {
       
   107         TUint32 objectHandle = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   108         // Check whether object handle is valid
       
   109         responseCode = MTPImageDpUtilits::VerifyObjectHandleL(iFramework, objectHandle, *iObjectInfo);
       
   110         }
       
   111     else if(EMTPRespCodeInvalidObjectHandle == responseCode) //we only check the parent handle
       
   112         {
       
   113         responseCode = EMTPRespCodeInvalidParentObject;
       
   114         }
       
   115     
       
   116     __FLOG_VA((_L8("CheckRequestL - Exit with responseCode = 0x%04X"), responseCode));
       
   117     __FLOG(_L8("<< CMTPImageDpCopyObject::CheckRequestL"));
       
   118     return responseCode;
       
   119     }
       
   120 
       
   121 /**
       
   122 MoveObject request handler
       
   123 */		
       
   124 void CMTPImageDpMoveObject::ServiceL()
       
   125     {
       
   126     __FLOG(_L8(">> CMTPImageDpMoveObject::ServiceL"));
       
   127     
       
   128     TMTPResponseCode ret = MoveObjectL();
       
   129     SendResponseL(ret);
       
   130     
       
   131     __FLOG(_L8("<< CMTPImageDpMoveObject::ServiceL")); 
       
   132     }
       
   133 
       
   134 /**
       
   135 A helper function of MoveObjectL.
       
   136 @param aNewFileName the new file name after the object is moved.
       
   137 */
       
   138 TMTPResponseCode CMTPImageDpMoveObject::MoveFileL(const TDesC& aOldFileName, const TDesC& aNewFileName)	
       
   139     {
       
   140     __FLOG(_L8(">> CMTPImageDpMoveObject::MoveFileL"));
       
   141     
       
   142     TMTPResponseCode responseCode = EMTPRespCodeOK;    
       
   143     /**
       
   144      * File system process the move operation has two different ways:
       
   145      * 1. move object between the same storage.
       
   146      *    under this situation, move operatoin will triggers the EFsRename event by file system.
       
   147      *    then harvester of MdS will directly update the uri of mde object.      
       
   148      *    
       
   149      * 2. move object tetween the different storage.
       
   150      *    uder this situation, move operation will triggers four events by file system:
       
   151      *    a. EFsFileReplace event for old uri object.
       
   152      *    b. EFsFileReplace event for new uri object.
       
   153      *    c. EFsFileSetModified event for DateModified property of object.
       
   154      *    d. EFsDelete event for old uri object.
       
   155      *    
       
   156      *    then harvester of MdS will generate four actions for the above events:
       
   157      *    a. EMdsFileReplaced action for old uri object, this action is a null operation, because no object associates with old uri.
       
   158      *    b. EMdsFileReplaced action for new uri object, this action will add a new mde object into database and 
       
   159      *       put this action into queue of image plugin to wait for execution.
       
   160      *    c. EmdsFileModified action for new object, this action will update the DateModified property of mde object and
       
   161      *       put this action into queue of image plugin to wait for execution.
       
   162      *    d. EmdsFileDeleted action for old object, this action will directly delete old mde object from database.
       
   163      */
       
   164     
       
   165     /**
       
   166      * image dp should update object properties in database to avoid race condition with MdS,
       
   167      * if move faile, it should rollback.
       
   168      */
       
   169     
       
   170     TUint oldStoradId = iObjectInfo->Uint(CMTPObjectMetaData::EStorageId);
       
   171     TUint oldParentHandle = iObjectInfo->Uint(CMTPObjectMetaData::EParentHandle);    
       
   172     iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aNewFileName);
       
   173     iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, iStorageId);
       
   174     iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, iNewParentHandle);
       
   175     iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);
       
   176     __FLOG_VA((_L16("CMTPImageDpMoveObject::MoveFileL - Update object info:%S"), &aNewFileName));
       
   177     
       
   178     TInt ret = MoveImageFile(aOldFileName, *iDest);
       
   179     if (ret != KErrNone)
       
   180         {
       
   181         //rollback
       
   182         __FLOG_VA((_L16("CMTPImageDpMoveObject::MoveFileL - Rollback")));
       
   183         iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, aOldFileName);
       
   184         iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, oldStoradId);
       
   185         iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, oldParentHandle);
       
   186         iFramework.ObjectMgr().ModifyObjectL(*iObjectInfo);       
       
   187         responseCode = EMTPRespCodeGeneralError;        
       
   188         }
       
   189     __FLOG_VA((_L8("CMTPImageDpMoveObject::MoveFileL - MoveImageFile:%d"), ret));
       
   190     
       
   191     __FLOG(_L8("<< CMTPImageDpMoveObject::MoveFileL")); 	
       
   192     return responseCode;
       
   193     }
       
   194 /**
       
   195 move object operations
       
   196 @return A valid MTP response code.
       
   197 */
       
   198 TMTPResponseCode CMTPImageDpMoveObject::MoveObjectL()
       
   199     {
       
   200     __FLOG(_L8(">> CMTPImageDpMoveObject::MoveObjectL"));
       
   201     TMTPResponseCode responseCode = EMTPRespCodeOK;
       
   202     GetParametersL();
       
   203     RBuf newObjectName;
       
   204     newObjectName.CreateL(KMaxFileName);
       
   205     newObjectName.CleanupClosePushL();
       
   206     newObjectName = *iDest;
       
   207     TFileName oldFileName = iObjectInfo->DesC(CMTPObjectMetaData::ESuid);
       
   208     TParsePtrC fileNameParser(oldFileName);
       
   209     if((newObjectName.Length() + fileNameParser.NameAndExt().Length()) <= newObjectName.MaxLength())
       
   210         {
       
   211         newObjectName.Append(fileNameParser.NameAndExt());
       
   212         responseCode = CanMoveObjectL(oldFileName, newObjectName);
       
   213         }
       
   214     else
       
   215         {
       
   216         responseCode = EMTPRespCodeGeneralError;
       
   217         }
       
   218         
       
   219     if(responseCode == EMTPRespCodeOK)
       
   220         {
       
   221         responseCode = MoveFileL(oldFileName, newObjectName);
       
   222         }
       
   223     CleanupStack::PopAndDestroy(); // newObjectName.
       
   224     __FLOG(_L8("<< CMTPImageDpMoveObject::MoveObjectL")); 	
       
   225     return responseCode;
       
   226     }
       
   227 
       
   228 /**
       
   229 Retrieve the parameters of the request
       
   230 */	
       
   231 void CMTPImageDpMoveObject::GetParametersL()
       
   232     {
       
   233     __FLOG(_L8(">> CMTPImageDpMoveObject::GetParametersL"));
       
   234     __ASSERT_DEBUG(iRequestChecker, Panic(EMTPImageDpRequestCheckNull));
       
   235     
       
   236     TUint32 objectHandle  = Request().Uint32(TMTPTypeRequest::ERequestParameter1);
       
   237     iStorageId = Request().Uint32(TMTPTypeRequest::ERequestParameter2);
       
   238     iNewParentHandle  = Request().Uint32(TMTPTypeRequest::ERequestParameter3);
       
   239     
       
   240     if(iNewParentHandle == 0)
       
   241         {
       
   242         SetDefaultParentObjectL();
       
   243         }
       
   244     else	
       
   245         {
       
   246         CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo(iNewParentHandle);
       
   247         __ASSERT_DEBUG(parentObjectInfo, Panic(EMTPImageDpObjectNull));
       
   248         delete iDest;
       
   249         iDest = NULL;
       
   250         iDest = parentObjectInfo->DesC(CMTPObjectMetaData::ESuid).AllocL();
       
   251         }
       
   252     __FLOG(_L8("<< CMTPImageDpMoveObject::GetParametersL"));
       
   253     }
       
   254     
       
   255 /**
       
   256 Get a default parent object, ff the request does not specify a parent object, 
       
   257 */
       
   258 void CMTPImageDpMoveObject::SetDefaultParentObjectL()
       
   259     {
       
   260     __FLOG(_L8(">> CMTPImageDpMoveObject::SetDefaultParentObjectL"));  
       
   261     const CMTPStorageMetaData& storage = iFramework.StorageMgr().StorageL(iStorageId);
       
   262     delete iDest;
       
   263     iDest = NULL;
       
   264     iDest = storage.DesC(CMTPStorageMetaData::EStorageSuid).AllocL();
       
   265     iNewParentHandle = KMTPHandleNoParent;
       
   266     __FLOG(_L8("<< CMTPImageDpMoveObject::SetDefaultParentObjectL"));  
       
   267     }
       
   268 
       
   269 /**
       
   270 Check if we can move the file to the new location
       
   271 */
       
   272 TMTPResponseCode CMTPImageDpMoveObject::CanMoveObjectL(const TDesC& aOldName, const TDesC& aNewName) const
       
   273     {
       
   274     __FLOG(_L8(">> CMTPImageDpMoveObject::CanMoveObjectL"));     
       
   275     TMTPResponseCode result = EMTPRespCodeOK;
       
   276 
       
   277     TEntry fileEntry;
       
   278     User::LeaveIfError(iFramework.Fs().Entry(aOldName, fileEntry));
       
   279     TDriveNumber drive(static_cast<TDriveNumber>(iFramework.StorageMgr().DriveNumber(iStorageId)));
       
   280     User::LeaveIfError(drive);
       
   281     TVolumeInfo volumeInfo;
       
   282     User::LeaveIfError(iFramework.Fs().Volume(volumeInfo, drive));
       
   283     
       
   284     if(volumeInfo.iFree < fileEntry.iSize)
       
   285         {
       
   286         result = EMTPRespCodeStoreFull;
       
   287         }
       
   288     else if (BaflUtils::FileExists(iFramework.Fs(), aNewName))			
       
   289         {
       
   290         result = EMTPRespCodeInvalidParentObject;
       
   291         }
       
   292     __FLOG_VA((_L8("CanMoveObjectL - Exit with response code 0x%04X"), result));
       
   293     __FLOG(_L8("<< CMTPImageDpMoveObject::CanMoveObjectL"));     
       
   294     return result;	
       
   295     }
       
   296 
       
   297 TInt CMTPImageDpMoveObject::MoveImageFile(const TDesC& aOldImageName, const TDesC& aNewImageName)
       
   298     {
       
   299     __FLOG(_L8(">> CMTPImageDpMoveObject::MoveImageFile"));
       
   300     __FLOG_VA((_L8("move image src: %S dest: %S"), &aOldImageName, &aNewImageName));        
       
   301     __FLOG(_L8("<< CMTPImageDpMoveObject::MoveImageFile"));
       
   302     return iFileMan->Move(aOldImageName, aNewImageName);
       
   303     }
       
   304 
       
   305 // End of file