14 * Description: Implement the operation: DeleteObject |
14 * Description: Implement the operation: DeleteObject |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <mtp/mmtpdataproviderframework.h> |
|
20 #include <mtp/mmtpobjectmgr.h> |
19 #include <mtp/mmtpobjectmgr.h> |
21 #include <mtp/mmtpreferencemgr.h> |
20 #include <mtp/mmtpreferencemgr.h> |
22 #include <mtp/cmtpobjectmetadata.h> |
|
23 |
21 |
24 #include "cdeleteobject.h" |
22 #include "cdeleteobject.h" |
25 #include "mmmtpdplogger.h" |
23 #include "mmmtpdplogger.h" |
26 #include "mmmtpdpconfig.h" |
24 #include "mmmtpdpconfig.h" |
27 #include "cmmmtpdpmetadataaccesswrapper.h" |
25 #include "cmmmtpdpmetadataaccesswrapper.h" |
28 #include "mmmtpdputility.h" |
26 #include "mmmtpdputility.h" |
29 |
27 |
30 static const TInt KMaxDeletionTimes = 10; |
28 const TInt KMaxDeletionTimes = 10; |
31 const TInt KDeletionThreshold = 100 * 1000; // (100 millisec) |
29 const TInt KDeletionThreshold = 100 * 1000; // (100 millisec) |
32 |
30 |
33 // ----------------------------------------------------------------------------- |
31 // ----------------------------------------------------------------------------- |
34 // Verification data for the DeleteObject request |
32 // Verification data for the DeleteObject request |
35 // ----------------------------------------------------------------------------- |
33 // ----------------------------------------------------------------------------- |
90 MMmMtpDpConfig& aDpConfig ) : |
88 MMmMtpDpConfig& aDpConfig ) : |
91 CRequestProcessor( aFramework, |
89 CRequestProcessor( aFramework, |
92 aConnection, |
90 aConnection, |
93 sizeof( KMTPDeleteObjectPolicy ) / sizeof( TMTPRequestElementInfo ), |
91 sizeof( KMTPDeleteObjectPolicy ) / sizeof( TMTPRequestElementInfo ), |
94 KMTPDeleteObjectPolicy ), |
92 KMTPDeleteObjectPolicy ), |
95 iObjectMgr( aFramework.ObjectMgr() ), |
|
96 iFs( aFramework.Fs() ), |
|
97 iObjectsToDelete( KMmMtpRArrayGranularity ), |
93 iObjectsToDelete( KMmMtpRArrayGranularity ), |
98 iDeleteError( KErrNone ), |
94 iDeleteError( KErrNone ), |
99 iDpConfig( aDpConfig ) |
95 iDpConfig( aDpConfig ) |
100 { |
96 { |
101 PRINT( _L( "Operation: DeleteObject(0x100B)" ) ); |
97 PRINT( _L( "Operation: DeleteObject(0x100B)" ) ); |
192 { |
188 { |
193 // Get the next object |
189 // Get the next object |
194 CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo |
190 CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo |
195 |
191 |
196 TUint32 handle = iObjectsToDelete[0]; |
192 TUint32 handle = iObjectsToDelete[0]; |
197 iObjectMgr.ObjectL( handle, *objectInfo ); |
193 iFramework.ObjectMgr().ObjectL( handle, *objectInfo ); |
198 TFileName fileName( objectInfo->DesC( CMTPObjectMetaData::ESuid ) ); |
194 TFileName fileName( objectInfo->DesC( CMTPObjectMetaData::ESuid ) ); |
199 PRINT2( _L( "MM MTP <> CDeleteObject::RunL delete object handle is 0x%x, fileName is %S" ), handle, &fileName ); |
195 PRINT2( _L( "MM MTP <> CDeleteObject::RunL delete object handle is 0x%x, fileName is %S" ), handle, &fileName ); |
200 |
196 |
201 if ( objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) == EMTPFormatCodeAssociation ) |
197 if ( objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) == EMTPFormatCodeAssociation ) |
202 { |
198 { |
232 |
228 |
233 // To capture special situation: After copy, move, rename playlist folder name, |
229 // To capture special situation: After copy, move, rename playlist folder name, |
234 // record in MPX is not inlined with framework db, playlist should not be deleted |
230 // record in MPX is not inlined with framework db, playlist should not be deleted |
235 // until next session. |
231 // until next session. |
236 // This is used to keep the same behavior in mass storage and device file manager. |
232 // This is used to keep the same behavior in mass storage and device file manager. |
237 if ( aObjectInfo.Uint(CMTPObjectMetaData::EFormatCode ) |
233 if ( aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) |
238 == EMTPFormatCodeAbstractAudioVideoPlaylist |
234 == EMTPFormatCodeAbstractAudioVideoPlaylist |
239 && !iDpConfig.GetWrapperL().IsExistL( fileName ) ) |
235 && !iDpConfig.GetWrapperL().IsExistL( fileName ) ) |
240 { |
236 { |
241 iDeleteError = KErrGeneral; |
237 iDeleteError = KErrGeneral; |
242 PRINT( _L( "MM MTP <= CDeleteObject::DeleteObjectL playlist file not exist in the MPX DB" ) ); |
238 PRINT( _L( "MM MTP <= CDeleteObject::DeleteObjectL playlist file not exist in the MPX DB" ) ); |
243 return; |
239 return; |
244 } |
240 } |
245 |
241 |
246 // 1. Delete object from file system |
242 // 1. Delete object from file system |
247 TEntry fileInfo; |
243 TEntry fileInfo; |
248 iFs.Entry( fileName, fileInfo ); |
244 iFramework.Fs().Entry( fileName, fileInfo ); |
249 if ( fileInfo.IsReadOnly() ) |
245 if ( fileInfo.IsReadOnly() ) |
250 { |
246 { |
251 iDeleteError = KErrAccessDenied; |
247 iDeleteError = KErrAccessDenied; |
252 PRINT1( _L( "MM MTP <= CDeleteObject::DeleteObjectL, \"%S\" is a read-only file"), &fileName ); |
248 PRINT1( _L( "MM MTP <= CDeleteObject::DeleteObjectL, \"%S\" is a read-only file"), &fileName ); |
253 return; |
249 return; |
255 // Some other component might be holding on to the file (MDS background harvesting), |
251 // Some other component might be holding on to the file (MDS background harvesting), |
256 // try again after 100 millisec, up to 10 times, before give up |
252 // try again after 100 millisec, up to 10 times, before give up |
257 TInt count = KMaxDeletionTimes; |
253 TInt count = KMaxDeletionTimes; |
258 while ( count > 0 ) |
254 while ( count > 0 ) |
259 { |
255 { |
260 iDeleteError = iFs.Delete( fileName ); |
256 iDeleteError = iFramework.Fs().Delete( fileName ); |
261 if ( iDeleteError == KErrNone || iDeleteError == KErrNotFound ) |
257 if ( iDeleteError == KErrNone || iDeleteError == KErrNotFound ) |
262 { |
258 { |
263 break; |
259 break; |
264 } |
260 } |
265 else if ( ( iDeleteError == KErrInUse ) && ( count > 1 ) ) |
261 else if ( ( iDeleteError == KErrInUse ) && ( count > 1 ) ) |
273 return; |
269 return; |
274 } |
270 } |
275 } |
271 } |
276 |
272 |
277 // 2. Delete object from metadata db |
273 // 2. Delete object from metadata db |
278 TRAP( iDeleteError, iDpConfig.GetWrapperL().DeleteObjectL( fileName, aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) )); |
274 TRAP( iDeleteError, iDpConfig.GetWrapperL().DeleteObjectL( aObjectInfo ) ); |
279 PRINT1( _L( "MM MTP <> CDeleteObject::DeleteObjectL, Delete from Media DB, err = %d" ), iDeleteError ); |
275 PRINT1( _L( "MM MTP <> CDeleteObject::DeleteObjectL, Delete from Media DB, err = %d" ), iDeleteError ); |
280 |
276 |
281 // 3. Delete object from framework db |
277 // 3. Delete object from framework db |
282 iObjectMgr.RemoveObjectL( aObjectInfo.Uint( CMTPObjectMetaData::EHandle ) ); |
278 iFramework.ObjectMgr().RemoveObjectL( aObjectInfo.Uint( CMTPObjectMetaData::EHandle ) ); |
283 |
279 |
284 // 4. If the object has references, Delete references from reference manager |
280 // 4. If the object has references, Delete references from reference manager |
285 if ( MmMtpDpUtility::HasReference( aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) ) ) |
281 if ( MmMtpDpUtility::HasReference( aObjectInfo.Uint( CMTPObjectMetaData::EFormatCode ) ) ) |
286 iFramework.ReferenceMgr().RemoveReferencesL( aObjectInfo.DesC( CMTPObjectMetaData::ESuid ) ); |
282 iFramework.ReferenceMgr().RemoveReferencesL( aObjectInfo.DesC( CMTPObjectMetaData::ESuid ) ); |
287 |
283 |
361 // else if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == 0 ) // We know that the device dp id is always 0, otherwise the whole MTP won't work. |
357 // else if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == 0 ) // We know that the device dp id is always 0, otherwise the whole MTP won't work. |
362 // iParentHandles.AppendL( handles[i] ); |
358 // iParentHandles.AppendL( handles[i] ); |
363 else |
359 else |
364 { |
360 { |
365 CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo |
361 CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo |
366 iObjectMgr.ObjectL( handles[i], *objectInfo ); |
362 iFramework.ObjectMgr().ObjectL( handles[i], *objectInfo ); |
367 if ( EMTPFormatCodeAssociation == objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) |
363 if ( EMTPFormatCodeAssociation == objectInfo->Uint( CMTPObjectMetaData::EFormatCode ) ) |
368 { |
364 { |
369 GetObjectHandlesL( KMTPStorageAll, handles[i] ); |
365 GetObjectHandlesL( KMTPStorageAll, handles[i] ); |
370 } |
366 } |
371 CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo |
367 CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo |