--- 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 <mtp/mmtpdataproviderframework.h>
#include <mtp/mmtpobjectmgr.h>
-#include <mtp/cmtpobjectmetadata.h>
+#include <mtp/mmtpreferencemgr.h>
#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] );