diff -r a05c44bc3c61 -r d881023c13eb mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cdeleteobject.cpp --- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cdeleteobject.cpp Fri Apr 16 15:28:14 2010 +0300 +++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cdeleteobject.cpp Mon May 03 12:58:40 2010 +0300 @@ -16,16 +16,17 @@ */ -#include #include -#include +#include #include "cdeleteobject.h" #include "mmmtpdplogger.h" #include "mmmtpdpconfig.h" #include "cmmmtpdpmetadataaccesswrapper.h" +#include "mmmtpdputility.h" -// static const TInt KMTPDriveGranularity = 5; +const TInt KMaxDeletionTimes = 10; +const TInt KDeletionThreshold = 100 * 1000; // (100 millisec) // ----------------------------------------------------------------------------- // Verification data for the DeleteObject request @@ -89,9 +90,7 @@ aConnection, sizeof( KMTPDeleteObjectPolicy ) / sizeof( TMTPRequestElementInfo ), KMTPDeleteObjectPolicy ), - iObjectMgr( aFramework.ObjectMgr() ), - iFs( aFramework.Fs() ), - iObjectsToDelete( KMmMtpRArrayGranularity ), + iObjectsToDelete( KMmMtpRArrayGranularity ), iDeleteError( KErrNone ), iDpConfig( aDpConfig ) { @@ -191,7 +190,7 @@ CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo TUint32 handle = iObjectsToDelete[0]; - iObjectMgr.ObjectL( handle, *objectInfo ); + iFramework.ObjectMgr().ObjectL( handle, *objectInfo ); TFileName fileName( objectInfo->DesC( CMTPObjectMetaData::ESuid ) ); PRINT2( _L( "MM MTP <> CDeleteObject::RunL delete object handle is 0x%x, fileName is %S" ), handle, &fileName ); @@ -225,14 +224,13 @@ TFileName fileName( aObjectInfo.DesC( CMTPObjectMetaData::ESuid ) ); PRINT1( _L( "MM MTP <> CDeleteObject::DeleteObjectL fileName = %S" ), &fileName ); - TParsePtrC parse( fileName ); - iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() ); + iDpConfig.GetWrapperL().SetStorageRootL( fileName ); // To capture special situation: After copy, move, rename playlist folder name, // record in MPX is not inlined with framework db, playlist should not be deleted // until next session. // This is used to keep the same behavior in mass storage and device file manager. - if ( aObjectInfo.Uint(CMTPObjectMetaData::EFormatCode ) + if ( aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) == EMTPFormatCodeAbstractAudioVideoPlaylist && !iDpConfig.GetWrapperL().IsExistL( fileName ) ) { @@ -243,26 +241,45 @@ // 1. Delete object from file system TEntry fileInfo; - iFs.Entry( fileName, fileInfo ); + iFramework.Fs().Entry( fileName, fileInfo ); if ( fileInfo.IsReadOnly() ) { iDeleteError = KErrAccessDenied; PRINT1( _L( "MM MTP <= CDeleteObject::DeleteObjectL, \"%S\" is a read-only file"), &fileName ); return; } - iDeleteError = iFs.Delete( fileName ); - if ( iDeleteError != KErrNone && iDeleteError != KErrNotFound ) + // Some other component might be holding on to the file (MDS background harvesting), + // try again after 100 millisec, up to 10 times, before give up + TInt count = KMaxDeletionTimes; + while ( count > 0 ) { - PRINT1( _L( "MM MTP <= CDeleteObject::DeleteObjectL, Delete from file system failed, err = %d" ), iDeleteError ); - return; + iDeleteError = iFramework.Fs().Delete( fileName ); + if ( iDeleteError == KErrNone || iDeleteError == KErrNotFound ) + { + break; + } + else if ( ( iDeleteError == KErrInUse ) && ( count > 1 ) ) + { + User::After( KDeletionThreshold ); + count--; + } + else + { + PRINT1( _L( "MM MTP <= CDeleteObject::DeleteObjectL, Delete from file system failed, err = %d" ), iDeleteError ); + return; + } } // 2. Delete object from metadata db - TRAP( iDeleteError, iDpConfig.GetWrapperL().DeleteObjectL( fileName, aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) )); + TRAP( iDeleteError, iDpConfig.GetWrapperL().DeleteObjectL( aObjectInfo ) ); PRINT1( _L( "MM MTP <> CDeleteObject::DeleteObjectL, Delete from Media DB, err = %d" ), iDeleteError ); // 3. Delete object from framework db - iObjectMgr.RemoveObjectL( aObjectInfo.Uint( CMTPObjectMetaData::EHandle ) ); + iFramework.ObjectMgr().RemoveObjectL( aObjectInfo.Uint( CMTPObjectMetaData::EHandle ) ); + + // 4. If the object has references, Delete references from reference manager + if ( MmMtpDpUtility::HasReference( aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) ) ) + iFramework.ReferenceMgr().RemoveReferencesL( aObjectInfo.DesC( CMTPObjectMetaData::ESuid ) ); PRINT( _L( "MM MTP <= CDeleteObject::DeleteObjectL" ) ); } @@ -342,7 +359,7 @@ else { CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo - iObjectMgr.ObjectL( handles[i], *objectInfo ); + iFramework.ObjectMgr().ObjectL( handles[i], *objectInfo ); if ( EMTPFormatCodeAssociation == objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) { GetObjectHandlesL( KMTPStorageAll, handles[i] );