mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadataaccesswrapper.cpp
branchRCL_3
changeset 17 780c925249c1
parent 14 05b0d2323768
child 19 51035f0751c2
--- a/mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadataaccesswrapper.cpp	Mon Mar 15 12:42:31 2010 +0200
+++ b/mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadataaccesswrapper.cpp	Wed Mar 31 22:26:09 2010 +0300
@@ -18,6 +18,8 @@
 
 #include <mtp/mmtpdataproviderframework.h>
 #include <mtp/mmtpobjectmgr.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/cmtpobjectmetadata.h>
 #include <bautils.h>
 #include <e32math.h>
 #include <e32property.h>
@@ -27,14 +29,14 @@
 #include "cmmmtpdpmetadatampxaccess.h"
 #include "cmmmtpdpmetadatavideoaccess.h"
 #include "mmmtpdputility.h"
+#include "tobjectdescription.h"
 #include "mmmtpdplogger.h"
 
-const TInt KMMMTPDummyFileArrayGranularity = 5;
+const TInt KMmMtpDummyFileArrayGranularity = 5;
 
-CMmMtpDpMetadataAccessWrapper* CMmMtpDpMetadataAccessWrapper::NewL( RFs& aRfs,
-    MMTPDataProviderFramework& aFramework )
+CMmMtpDpMetadataAccessWrapper* CMmMtpDpMetadataAccessWrapper::NewL( MMTPDataProviderFramework& aFramework )
     {
-    CMmMtpDpMetadataAccessWrapper* me = new (ELeave) CMmMtpDpMetadataAccessWrapper( aRfs, aFramework );
+    CMmMtpDpMetadataAccessWrapper* me = new (ELeave) CMmMtpDpMetadataAccessWrapper( aFramework );
     CleanupStack::PushL( me );
     me->ConstructL();
     CleanupStack::Pop( me );
@@ -42,10 +44,9 @@
     return me;
     }
 
-CMmMtpDpMetadataAccessWrapper::CMmMtpDpMetadataAccessWrapper( RFs& aRfs,
-    MMTPDataProviderFramework& aFramework ) :
-    iRfs( aRfs ),
-    iFramework( aFramework )
+CMmMtpDpMetadataAccessWrapper::CMmMtpDpMetadataAccessWrapper( MMTPDataProviderFramework& aFramework ) :
+    iFramework( aFramework ),
+    iFs( aFramework.Fs() )
     {
     // Do nothing
     }
@@ -59,11 +60,11 @@
     {
     PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::ConstructL" ) );
 
-    iMmMtpDpMetadataMpxAccess = CMmMtpDpMetadataMpxAccess::NewL( iRfs, iFramework );
+    iMmMtpDpMetadataMpxAccess = CMmMtpDpMetadataMpxAccess::NewL( iFs );
 
-    iMmMtpDpMetadataVideoAccess = CMmMtpDpMetadataVideoAccess::NewL( iRfs );
+    iMmMtpDpMetadataVideoAccess = CMmMtpDpMetadataVideoAccess::NewL( iFs );
 
-    iAbstractMediaArray = new ( ELeave ) CDesCArrayFlat( KMMMTPDummyFileArrayGranularity );
+    iAbstractMediaArray = new ( ELeave ) CDesCArrayFlat( KMmMtpDummyFileArrayGranularity );
 
     // Create the PS key to notify subscribers that MTP mode is activated
     _LIT_SECURITY_POLICY_C1(KKeyReadPolicy, ECapabilityReadUserData);
@@ -100,22 +101,24 @@
     }
 
 // -----------------------------------------------------------------------------
-// CMmMtpDpMetadataAccessWrapper::SetAbstractMediaL
+// CMmMtpDpMetadataAccessWrapper::SetReferenceL
 // Set abstract media to DB
 // -----------------------------------------------------------------------------
 //
-EXPORT_C void CMmMtpDpMetadataAccessWrapper::SetAbstractMediaL( const TDesC& aAbstractMediaFileName, 
-    CDesCArray& aRefFileArray, 
-    TMPXGeneralCategory aCategory )
+EXPORT_C void CMmMtpDpMetadataAccessWrapper::SetReferenceL( const CMTPObjectMetaData& aObject,
+    CDesCArray& aRefFileArray )
     {
-    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::SetAbstractMediaL aAbstractMediaFileName = %S" ), &aAbstractMediaFileName );
+    TPtrC refOwner( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::SetReferenceL reference owner = %S" ),
+        &refOwner );
 
-    if ( !MmMtpDpUtility::IsVideoL( aAbstractMediaFileName, iFramework ) )
+    TMPXGeneralCategory category = Category( aObject );
+    if ( category == EMPXPlaylist || category == EMPXAbstractAlbum )
         {
-        iMmMtpDpMetadataMpxAccess->SetAbstractMediaL( aAbstractMediaFileName, aRefFileArray, aCategory );
+        iMmMtpDpMetadataMpxAccess->SetReferenceL( refOwner, aRefFileArray, category );
         }
 
-    PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::SetAbstractMediaL" ) );
+    PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::SetReferenceL" ) );
     }
 
 // ---------------------------------------------------------------------------
@@ -129,18 +132,53 @@
     {
     PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::GetObjectMetadataValueL" ) );
 
-    TPtrC fullFileName( aObjectMetaData.DesC( CMTPObjectMetaData::ESuid ) );
-    if ( !MmMtpDpUtility::IsVideoL( fullFileName, iFramework ) )
+    TMPXGeneralCategory category = Category( aObjectMetaData );
+    switch ( category )
         {
-        iMmMtpDpMetadataMpxAccess->GetObjectMetadataValueL( aPropCode,
-            aNewData,
-            aObjectMetaData );
-        }
-    else
-        {
-        iMmMtpDpMetadataVideoAccess->GetObjectMetadataValueL( aPropCode,
-            aNewData,
-            aObjectMetaData );
+        case EMPXAbstractAlbum:
+            if ( aPropCode == EMTPObjectPropCodeDateAdded && EMTPTypeString == aNewData.Type() )
+                {
+                TBuf<KMtpMaxDateTimeStringLength> timeStr;
+                MmMtpDpUtility::GetObjectDateModifiedL( iFs,
+                    aObjectMetaData.DesC( CMTPObjectMetaData::ESuid ),
+                    timeStr );
+                PRINT1( _L( "MM MTP <> CGetObjectPropList::ServiceOneObjectPropertyL Date time %S" ), &timeStr );
+
+                ( ( CMTPTypeString & ) aNewData ).SetL( timeStr );
+                break;
+                }
+            // else
+            // get from mpx
+        case EMPXPlaylist:
+        case EMPXSong:
+            {
+            iMmMtpDpMetadataMpxAccess->GetObjectMetadataValueL( aPropCode,
+                aNewData,
+                aObjectMetaData.DesC( CMTPObjectMetaData::ESuid ),
+                category );
+            }
+            break;
+        case EMPXVideo:
+            if ( aPropCode == EMTPObjectPropCodeDateAdded && EMTPTypeString == aNewData.Type() )
+                {
+                TBuf<KMtpMaxDateTimeStringLength> timeStr;
+                MmMtpDpUtility::GetObjectDateModifiedL( iFs,
+                    aObjectMetaData.DesC( CMTPObjectMetaData::ESuid ),
+                    timeStr );
+                PRINT1( _L( "MM MTP <> CGetObjectPropList::ServiceOneObjectPropertyL Date time %S" ), &timeStr );
+
+                ( ( CMTPTypeString & ) aNewData ).SetL( timeStr );
+                }
+            else
+                {
+                iMmMtpDpMetadataVideoAccess->GetObjectMetadataValueL( aPropCode,
+                    aNewData,
+                    aObjectMetaData );
+                }
+            break;
+        default:
+            // do nothing
+            break;
         }
 
     PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::GetObjectMetadataValueL" ) );
@@ -157,99 +195,90 @@
     {
     PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::SetObjectMetadataValueL" ) );
 
-    // In SendObjectPropList, formatCode has already know, but object handle has not been committed into db
-    // In that case, format couldn't be get from object manager
-    TUint formatCode = aObjectMetaData.Uint( CMTPObjectMetaData::EFormatCode );
-    TUint formatSubCode = aObjectMetaData.Uint( CMTPObjectMetaData::EFormatSubCode );
-
-    TBool isVideo = EFalse;
-    isVideo = MmMtpDpUtility::IsVideoL( formatCode, formatSubCode );
-
-    if ( isVideo )
+    TMPXGeneralCategory category = Category( aObjectMetaData );
+    switch ( category )
         {
-        iMmMtpDpMetadataVideoAccess->SetObjectMetadataValueL( aPropCode,
-            aNewData,
-            aObjectMetaData );
-        }
-    else
-        {
-        iMmMtpDpMetadataMpxAccess->SetObjectMetadataValueL( aPropCode,
-            aNewData,
-            aObjectMetaData );
+        case EMPXAbstractAlbum:
+        case EMPXSong:
+        case EMPXPlaylist:
+            iMmMtpDpMetadataMpxAccess->SetObjectMetadataValueL( aPropCode,
+                aNewData,
+                aObjectMetaData.DesC( CMTPObjectMetaData::ESuid ),
+                category );
+            break;
+        case EMPXVideo:
+            iMmMtpDpMetadataVideoAccess->SetObjectMetadataValueL( aPropCode,
+                aNewData,
+                aObjectMetaData );
+            break;
+        default:
+            break;
         }
 
     PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::SetObjectMetadataValueL" ) );
     }
 
 // ---------------------------------------------------------------------------
-// CMmMtpDpMetadataAccessWrapper::SetObjectMetadataValueL
+// CMmMtpDpMetadataAccessWrapper::RenameObjectL
 // Renames the file part of a record in the collection database
 // ---------------------------------------------------------------------------
 //
-EXPORT_C void CMmMtpDpMetadataAccessWrapper::RenameObjectL( const TDesC& aOldFileName,
+EXPORT_C void CMmMtpDpMetadataAccessWrapper::RenameObjectL( const CMTPObjectMetaData& aOldObject,
     const TDesC& aNewFileName )
     {
+    TPtrC oldFileName( aOldObject.DesC( CMTPObjectMetaData::ESuid ) );
     PRINT2( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::RenameObjectL old = %S, new = %S" ),
-        &aOldFileName,
+        &oldFileName,
         &aNewFileName );
 
-    if ( MmMtpDpUtility::IsVideoL( aOldFileName, iFramework ) )
-        {
-        iMmMtpDpMetadataVideoAccess->RenameRecordL( aOldFileName, aNewFileName );
-        }
-    else
+    TMPXGeneralCategory category = Category( aOldObject );
+    switch ( category )
         {
-        CMTPObjectMetaData* object = CMTPObjectMetaData::NewLC();
-        iFramework.ObjectMgr().ObjectL( aOldFileName, *object );
-        iMmMtpDpMetadataMpxAccess->RenameObjectL( aOldFileName,
-            aNewFileName,
-            object->Uint( CMTPObjectMetaData::EFormatCode ) );
-        CleanupStack::PopAndDestroy( object );
+        case EMPXSong:
+        case EMPXAbstractAlbum:
+        case EMPXPlaylist:
+            {
+            iMmMtpDpMetadataMpxAccess->RenameObjectL( oldFileName,
+                aNewFileName,
+                category );
+            }
+            break;
+        case EMPXVideo:
+            iMmMtpDpMetadataVideoAccess->RenameRecordL( oldFileName, aNewFileName );
+            break;
+        default:
+            break;
         }
 
+
     PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::RenameObjectL" ) );
     }
 
 // ---------------------------------------------------------------------------
-// CMmMtpDpMetadataAccessWrapper::SetObjectMetadataValueL
+// CMmMtpDpMetadataAccessWrapper::DeleteObjectL
 // Deletes metadata information associated with the object
 // ---------------------------------------------------------------------------
 //
-void CMmMtpDpMetadataAccessWrapper::DeleteObjectL( const TDesC& aFullFileName,
-    const TUint aFormatCode )
+void CMmMtpDpMetadataAccessWrapper::DeleteObjectL( const CMTPObjectMetaData& aObject )
     {
-    PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::DeleteObjectL" ) );
-
-    TMPXGeneralCategory category = Category( aFormatCode );
+    TPtrC fileName( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::DeleteObjectL name = %S" ), &fileName );
 
-    // Have to do this.  File might not be in file system anymore, have to
-    // reply on ObjectManager
-    if ( ( aFormatCode == EMTPFormatCodeMP4Container )
-        || ( aFormatCode == EMTPFormatCode3GPContainer )
-        || ( aFormatCode == EMTPFormatCodeASF ) )
-        {
-        if ( MmMtpDpUtility::IsVideoL( aFullFileName, iFramework ) )
-            {
-            category = EMPXVideo;
-            }
-        else
-            {
-            category = EMPXSong;
-            }
-        }
+    TMPXGeneralCategory category = Category( aObject );
 
     switch ( category )
         {
+        case EMPXSong:
+        case EMPXAbstractAlbum:
         case EMPXPlaylist:
-        case EMPXSong:
             {
-            iMmMtpDpMetadataMpxAccess->DeleteObjectL( aFullFileName, category );
+            iMmMtpDpMetadataMpxAccess->DeleteObjectL( fileName, category );
             }
             break;
 
         case EMPXVideo:
             {
-            iMmMtpDpMetadataVideoAccess->DeleteRecordL( aFullFileName );
+            iMmMtpDpMetadataVideoAccess->DeleteRecordL( fileName );
             }
             break;
 
@@ -275,19 +304,25 @@
 
     PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::SetStorageRootL" ) );
     }
+
 // -----------------------------------------------------------------------------
 // CMmMtpDpMetadataMpxAccess::SetImageObjPropL
 // set image specific properties specific to videos
 // -----------------------------------------------------------------------------
 //
-void CMmMtpDpMetadataAccessWrapper::SetImageObjPropL( const TDesC& aFullFileName,
+void CMmMtpDpMetadataAccessWrapper::SetImageObjPropL( const CMTPObjectMetaData& aObject,
     const TUint32 aWidth,
     const TUint32 aHeight )
     {
-    iMmMtpDpMetadataVideoAccess->SetStorageRootL( aFullFileName );
-    iMmMtpDpMetadataVideoAccess->SetImageObjPropL( aFullFileName,
-        aWidth,
-        aHeight );
+    TMPXGeneralCategory category = Category( aObject );
+    if ( category == EMPXVideo )
+        {
+        TPtrC fullFileName( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+        iMmMtpDpMetadataVideoAccess->SetStorageRootL( fullFileName );
+        iMmMtpDpMetadataVideoAccess->SetImageObjPropL( fullFileName,
+            aWidth,
+            aHeight );
+        }
     }
 
 // -----------------------------------------------------------------------------
@@ -295,16 +330,19 @@
 // get image specific properties specific to videos
 // -----------------------------------------------------------------------------
 //
-void CMmMtpDpMetadataAccessWrapper::GetImageObjPropL( const TDesC& aFullFileName,
+void CMmMtpDpMetadataAccessWrapper::GetImageObjPropL( const CMTPObjectMetaData& aObject,
     TUint32& aWidth,
     TUint32& aHeight )
     {
-    if ( MmMtpDpUtility::IsVideoL( aFullFileName, iFramework ) )
+    TMPXGeneralCategory category = Category( aObject );
+    if ( category == EMPXVideo )
         {
-        iMmMtpDpMetadataVideoAccess->SetStorageRootL( aFullFileName );
-        iMmMtpDpMetadataVideoAccess->GetImageObjPropL( aFullFileName, aWidth, aHeight );
+        TPtrC fullFileName( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+        iMmMtpDpMetadataVideoAccess->SetStorageRootL( fullFileName );
+        iMmMtpDpMetadataVideoAccess->GetImageObjPropL( fullFileName, aWidth, aHeight );
         }
     }
+
 // -----------------------------------------------------------------------------
 // CMmMtpDpMetadataAccessWrapper::OpenSessionL
 // Called when the MTP session is initialised
@@ -339,29 +377,61 @@
 // Get category according format code
 // ---------------------------------------------------------------------------
 //
-TMPXGeneralCategory CMmMtpDpMetadataAccessWrapper::Category( const TUint aFormatCode )
+TMPXGeneralCategory CMmMtpDpMetadataAccessWrapper::Category( const CMTPObjectMetaData& aObject )
     {
     TMPXGeneralCategory category = EMPXNoCategory;
-    switch ( aFormatCode )
+    TUint formatCode = aObject.Uint( CMTPObjectMetaData::EFormatCode );
+    switch ( formatCode )
         {
+        case EMTPFormatCodeASF:
+        case EMTPFormatCodeMP4Container:
+        case EMTPFormatCode3GPContainer:
+            {
+            TUint aSubFormatCode = aObject.Uint( CMTPObjectMetaData::EFormatSubCode );
+            if ( aSubFormatCode == EMTPSubFormatCodeUnknown )
+                {
+                category = ContainerCategory( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+                if ( category == EMPXSong )
+                    aSubFormatCode = EMTPSubFormatCodeAudio;
+                else if ( category == EMPXVideo )
+                    aSubFormatCode = EMTPSubFormatCodeVideo;
+                else
+                    aSubFormatCode = EMTPSubFormatCodeUndefine;
+                const_cast<CMTPObjectMetaData&>(aObject).SetUint( CMTPObjectMetaData::EFormatSubCode, aSubFormatCode );
+                // If object doesn't exist, do nothing
+                TRAP_IGNORE( iFramework.ObjectMgr().ModifyObjectL( aObject ) );
+                }
+            else if ( aSubFormatCode == EMTPSubFormatCodeAudio )
+                category = EMPXSong;
+            else if ( aSubFormatCode == EMTPSubFormatCodeVideo )
+                category = EMPXVideo;
+            else if( aSubFormatCode == EMTPSubFormatCodeUndefine )
+                category = EMPXOther;
+            }
+            break;
+
         case EMTPFormatCodeMP3:
         case EMTPFormatCodeWAV:
         case EMTPFormatCodeWMA:
         case EMTPFormatCodeAAC:
-        case EMTPFormatCodeASF:
-        case EMTPFormatCodeMP4Container:
-        case EMTPFormatCode3GPContainer:
             {
             category = EMPXSong;
             }
             break;
 
+        case EMTPFormatCodeM3UPlaylist:
         case EMTPFormatCodeAbstractAudioVideoPlaylist:
             {
             category = EMPXPlaylist;
             }
             break;
 
+        case EMTPFormatCodeAbstractAudioAlbum:
+            {
+            category = EMPXAbstractAlbum;
+            }
+            break;
+
         case EMTPFormatCodeWMV:
             {
             category = EMPXVideo;
@@ -371,6 +441,46 @@
         default:
             break;
         }
+    PRINT1( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::Category category = %d" ), category );
+    return category;
+    }
+
+TMPXGeneralCategory CMmMtpDpMetadataAccessWrapper::ContainerCategory( const TDesC& aFullFileName )
+    {
+    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::ContainerCategory aFullFileName = %S" ), &aFullFileName );
+
+    TMPXGeneralCategory category = EMPXNoCategory;
+    TParsePtrC pathParser( aFullFileName );
+    TPtrC ext( pathParser.Ext() );
+
+    if ( ext.Length() <= 0 )
+        category = EMPXOther;
+
+    if ( ext.CompareF( KTxtExtensionMP4 ) == 0
+        || ext.CompareF( KTxtExtension3GP ) == 0
+        || ext.CompareF( KTxtExtension3G2 ) == 0
+        || ext.CompareF( KTxtExtensionODF ) == 0
+        || ext.CompareF( KTxtExtensionASF ) == 0 )
+        {
+        HBufC8* mimetype = MmMtpDpUtility::ContainerMimeType( aFullFileName );
+        if ( mimetype != NULL )
+            {
+            TMmMtpSubFormatCode subFormatCode = MmMtpDpUtility::SubFormatCodeFromMime( *mimetype );
+
+            if ( subFormatCode == EMTPSubFormatCodeVideo )
+                category = EMPXVideo;
+            else if( subFormatCode == EMTPSubFormatCodeAudio )
+                category = EMPXSong;
+            else
+                category = EMPXOther;
+            }
+        }
+    else if ( ext.CompareF( KTxtExtensionO4V ) == 0 )
+        category = EMPXVideo;
+    else
+        category = EMPXOther;
+
+    PRINT1( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::ContainerCategory, category = %d" ), category );
     return category;
     }
 
@@ -408,38 +518,27 @@
 // Add object (music, video, playlist and abstract media) info to DB
 // -----------------------------------------------------------------------------
 //
-void CMmMtpDpMetadataAccessWrapper::AddObjectL( const TDesC& aFullFileName, TUint aFormatCode, TUint aSubFormatCode )
+void CMmMtpDpMetadataAccessWrapper::AddObjectL( const CMTPObjectMetaData& aObject )
     {
-    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL aFullFileName = %S" ), &aFullFileName );
+    PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL" ) );
+    TMPXGeneralCategory category = Category( aObject );
 
-    if ( aFullFileName.Length() <= 0 )
-        {
-        User::Leave( KErrArgument );
-        }
-    if ( MmMtpDpUtility::IsVideoL( aFormatCode, aSubFormatCode ) )
+    TPtrC fullFileName( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+    if ( category == EMPXVideo )
         {
         PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL Addvideo" ) );
-        iMmMtpDpMetadataVideoAccess->AddVideoL( aFullFileName );
+        iMmMtpDpMetadataVideoAccess->AddVideoL( fullFileName );
         }
-    else
+    else if ( category == EMPXPlaylist || category == EMPXAbstractAlbum )
         {
-        if ( aFormatCode == EMTPFormatCodeM3UPlaylist
-            || aFormatCode == EMTPFormatCodeMPLPlaylist
-            || aFormatCode == EMTPFormatCodeAbstractAudioVideoPlaylist
-            || aFormatCode == EMTPFormatCodeAbstractAudioPlaylist
-            || aFormatCode == EMTPFormatCodeAbstractVideoPlaylist
-            || aFormatCode == EMTPFormatCodeASXPlaylist
-            || aFormatCode == EMTPFormatCodePLSPlaylist )
-            {
-            PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL AddPlaylist" ) );
-            iMmMtpDpMetadataMpxAccess->AddAbstractMediaL( aFullFileName,
-                EMPXPlaylist );
-            }
-        else
-            {
-            PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL AddSong" ) );
-            iMmMtpDpMetadataMpxAccess->AddSongL( aFullFileName );
-            }
+        PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL AddPlaylist" ) );
+        iMmMtpDpMetadataMpxAccess->AddAbstractMediaL( fullFileName,
+            category );
+        }
+    else if ( category == EMPXSong )
+        {
+        PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL AddSong" ) );
+        iMmMtpDpMetadataMpxAccess->AddSongL( fullFileName );
         }
 
     PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::AddObjectL" ) );
@@ -518,7 +617,7 @@
         EMTPFormatCodeAbstractAudioVideoPlaylist )
         {
         RFile newfile;
-        TInt err = newfile.Replace( iFramework.Fs(), aPlaylistName, EFileWrite );
+        TInt err = newfile.Replace( iFs, aPlaylistName, EFileWrite );
 
         if ( err != KErrNone )
             {
@@ -529,7 +628,7 @@
             {
             err = newfile.Flush();
             newfile.Close();
-            err = iFramework.Fs().SetAtt( aPlaylistName, KEntryAttSystem | KEntryAttHidden,
+            err = iFs.SetAtt( aPlaylistName, KEntryAttSystem | KEntryAttHidden,
                 KEntryAttReadOnly | KEntryAttNormal );
             if ( err != KErrNone )
                 PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::CreateDummyFile Dummy Playlist file created. err = %d" ), err );
@@ -539,7 +638,7 @@
 
 // -----------------------------------------------------------------------------
 // CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles
-// Remove all dummy file of which format is "pla", and leave the "m3u"
+// Remove all dummy file of which format is "pla" and "alb", and leave the "m3u"
 // -----------------------------------------------------------------------------
 //
 void CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles()
@@ -547,25 +646,43 @@
     PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles" ) );
 
     TInt count = iAbstractMediaArray->Count();
+    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles, count = %d" ), count );
     // Check if playlist file is a dummy file or an imported file
     for ( TInt i = 0; i < count; i++ )
         {
-        TPtrC dummyFileName( (*iAbstractMediaArray)[i] );
-        if ( MmMtpDpUtility::FormatFromFilename( dummyFileName ) !=
-            EMTPFormatCodeM3UPlaylist )
+        TPtrC fileName( (*iAbstractMediaArray)[i] );
+        PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles, fileName = %S" ), &fileName );
+        
+        TMTPFormatCode format = MmMtpDpUtility::FormatFromFilename( fileName );
+        PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles, format = 0x%x" ), format );
+        if ( format == EMTPFormatCodeAbstractAudioAlbum )
             {
-            // delete the virtual playlist
-            // iFramework has release don't use iFramework.FS()
-            TInt err = iRfs.Delete( ( *iAbstractMediaArray )[i] );
+            // delete the abstract album if its size is zero
+            TEntry entry;
+            TInt err = iFs.Entry( fileName, entry );
+            if ( err == KErrNone && entry.iSize == 0 )
+                {
+                TRAP( err, iMmMtpDpMetadataMpxAccess->DeleteObjectL( fileName, EMPXAbstractAlbum ) );
+                if( err == KErrNone )
+                    {
+                    err = iFs.Delete( fileName );
+                    }
+                }
+            PRINT3( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFile filename = %S, err %d, entry.iSize = %d" ),
+                &fileName, err, entry.iSize );
+            }
+        else if ( format != EMTPFormatCodeM3UPlaylist )
+            {
+            TInt err = iFs.Delete( fileName );
 
             PRINT2( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFile filename = %S, err %d" ),
-                &dummyFileName,
+                &fileName,
                 err );
             }
         else
             {
             // leave the Imported playlist in the file system
-            PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFile, Don't delete m3u file [%S]" ), &dummyFileName );
+            PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFile, Don't delete m3u file [%S]" ), &fileName );
             }
         }
     PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles" ) );