mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/ccopyobject.cpp
changeset 25 d881023c13eb
parent 0 a2952bb97e68
child 32 edd273b3192a
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/ccopyobject.cpp	Fri Apr 16 15:28:14 2010 +0300
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/ccopyobject.cpp	Mon May 03 12:58:40 2010 +0300
@@ -1,28 +1,25 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:  Implement the operation: CopyObject
-*
-*/
-
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:  Implement the operation: CopyObject
+ *
+ */
 
 #include <bautils.h>
 
-#include <mtp/mmtpdataproviderframework.h>
 #include <mtp/mmtpobjectmgr.h>
 #include <mtp/mmtpreferencemgr.h>
 #include <mtp/mmtpstoragemgr.h>
-#include <mtp/cmtpobjectmetadata.h>
 #include <mtp/cmtptypestring.h>
 #include <mtp/cmtptypearray.h>
 #include <mtp/cmtptypeobjectproplist.h>
@@ -33,16 +30,17 @@
 #include "mmmtpdputility.h"
 #include "mmmtpdpconfig.h"
 #include "cmmmtpdpmetadataaccesswrapper.h"
+#include "cpropertysettingutility.h"
 
 /**
-* Verification data for the CopyObject request
-*/
+ * Verification data for the CopyObject request
+ */
 const TMTPRequestElementInfo KMTPCopyObjectPolicy[] =
     {
         {
         TMTPTypeRequest::ERequestParameter1,
         EMTPElementTypeObjectHandle,
-        EMTPElementAttrFileOrDir,
+        EMTPElementAttrFile,
         0,
         0,
         0
@@ -74,14 +72,12 @@
     {
     Cancel();
 
+    delete iTargetObject;
     delete iDest;
-    delete iFileMan;
-    iObjectHandles.Close();
+
     if ( iPropertyElement )
         delete iPropertyElement;
     delete iPropertyList;
-    delete iPathToCopy;
-    delete iNewRootFolder;
     }
 
 // -----------------------------------------------------------------------------
@@ -92,17 +88,32 @@
 EXPORT_C CCopyObject::CCopyObject( MMTPDataProviderFramework& aFramework,
     MMTPConnection& aConnection,
     MMmMtpDpConfig& aDpConfig ) :
-    CRequestProcessor( aFramework,
-        aConnection,
-        sizeof ( KMTPCopyObjectPolicy ) / sizeof(TMTPRequestElementInfo),
-        KMTPCopyObjectPolicy ),
-    iDpConfig( aDpConfig ),
-    iObjectHandles( KMmMtpRArrayGranularity )
+        CRequestProcessor( aFramework,
+            aConnection, 
+            sizeof( KMTPCopyObjectPolicy ) / sizeof( TMTPRequestElementInfo ),
+            KMTPCopyObjectPolicy ),
+        iDpConfig( aDpConfig ),
+        iSourceObject( NULL ),
+        iTargetObject( NULL )
     {
     PRINT( _L( "Operation: CopyObject(0x101A)" ) );
     }
 
 // -----------------------------------------------------------------------------
+// CCopyObject::ConstructL
+// Second phase constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CCopyObject::ConstructL()
+    {
+    iPropertyList = CMTPTypeObjectPropList::NewL();
+
+    // Set the CenRep value of MTP status,
+    // also need to do in other processors which related to MPX
+    SetPSStatus();
+    }
+
+// -----------------------------------------------------------------------------
 // CCopyObject::ServiceL
 // CopyObject request handler
 // -----------------------------------------------------------------------------
@@ -110,223 +121,55 @@
 EXPORT_C void CCopyObject::ServiceL()
     {
     PRINT( _L( "MM MTP => CCopyObject::ServiceL" ) );
-    iHandle = KMTPHandleNone;
 
-    CopyObjectL( iHandle );
+    CopyObjectL();
 
     PRINT( _L( "MM MTP <= CCopyObject::ServiceL" ) );
     }
 
 // -----------------------------------------------------------------------------
-// CCopyObject::ConstructL
-// Second phase constructor
-// -----------------------------------------------------------------------------
-//
-EXPORT_C void CCopyObject::ConstructL()
-    {
-    CActiveScheduler::Add( this );
-
-    iPropertyList = CMTPTypeObjectPropList::NewL();
-
-    // Set the CenRep value of MTP status,
-    // also need to do in other processors which related to MPX
-    SetPSStatus();
-    }
-
-// -----------------------------------------------------------------------------
-// CCopyObject::RunL
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C void CCopyObject::RunL()
-    {
-    PRINT( _L( "MM MTP => CCopyObject::RunL" ) );
-
-    if ( iCopyObjectIndex < iNumberOfObjects )
-        {
-        CopyAndUpdateL( iObjectHandles[iCopyObjectIndex++] );
-
-        TRequestStatus* status = &iStatus;
-        User::RequestComplete( status, iStatus.Int() );
-        SetActive();
-        }
-    else
-        {
-        PRINT1( _L( "MM MTP <> CCopyObject::RunL iHandle = 0x%x" ), iHandle );
-        SendResponseL( EMTPRespCodeOK, 1, &iHandle );
-        }
-
-    PRINT( _L( "MM MTP <= CCopyObject::RunL" ) );
-    }
-
-// -----------------------------------------------------------------------------
-// CCopyObject::CopyFileL
-// A helper function of CopyObjectL
-// -----------------------------------------------------------------------------
-//
-TUint32 CCopyObject::CopyFileL( const TDesC& aNewFileName )
-    {
-    const TDesC& suid( iObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
-    PRINT2( _L( "MM MTP => CCopyObject::CopyFileL old name = %S, aNewFileName = %S" ),
-        &suid,
-        &aNewFileName );
-
-    GetPreviousPropertiesL( *iObjectInfo );
-    User::LeaveIfError( iFileMan->Copy( suid, aNewFileName ) ); // iDest just folder
-    User::LeaveIfError( iFramework.Fs().SetModified( aNewFileName, iPreviousModifiedTime ) );
-    TUint32 handle = UpdateObjectInfoL( suid, aNewFileName );
-
-    PRINT1( _L( "MM MTP <= CCopyObject::CopyFileL handle = 0x%x" ), handle );
-
-    return handle;
-    }
-
-// -----------------------------------------------------------------------------
-// CCopyObject::GenerateObjectHandleListL
-// Generate the list of handles that need to be copied to the new location
-// -----------------------------------------------------------------------------
-//
-void CCopyObject::GenerateObjectHandleListL( TUint32 aParentHandle )
-    {
-    PRINT1( _L( "MM MTP => CCopyObject::GenerateObjectHandleListL aParentHandle = 0x%x" ),
-        aParentHandle );
-    RMTPObjectMgrQueryContext context;
-    RArray<TUint> handles;
-    CleanupClosePushL( context ); // + context
-    CleanupClosePushL( handles ); // + handles
-
-    TMTPObjectMgrQueryParams params( KMTPStorageAll, KMTPFormatsAll,
-            aParentHandle );
-    do
-        {
-        iFramework.ObjectMgr().GetObjectHandlesL( params, context, handles );
-
-        TInt numberOfObjects = handles.Count();
-        for ( TInt i = 0; i < numberOfObjects; i++ )
-            {
-            if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == iFramework.DataProviderId() )
-                {
-                iObjectHandles.AppendL( handles[i] );
-                continue;
-                }
-
-            // Folder
-            if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i] ) == 0 ) // We know that the device dp id is always 0, otherwise the whole MTP won't work.
-                {
-                GenerateObjectHandleListL( handles[i] );
-                }
-            }
-        }
-    while ( !context.QueryComplete() );
-
-    CleanupStack::PopAndDestroy( &handles ); // - handles
-    CleanupStack::PopAndDestroy( &context ); // - context
-    PRINT( _L( "MM MTP <= CCopyObject::GenerateObjectHandleListL" ) );
-    }
-
-// -----------------------------------------------------------------------------
-// CCopyObject::CopyFolderL
-// A helper function of CopyObjectL
-// -----------------------------------------------------------------------------
-//
-TUint32 CCopyObject::CopyFolderL( const TDesC& aNewFolderName )
-    {
-    PRINT1( _L( "MM MTP => CCopyObject::CopyFolderL aNewFolderName = %S" ), &aNewFolderName );
-    TUint32 handle = iFramework.ObjectMgr().HandleL( aNewFolderName ); // just get it
-
-    GenerateObjectHandleListL( iObjectInfo->Uint( CMTPObjectMetaData::EHandle ) );
-    iCopyObjectIndex = 0;
-    iNumberOfObjects = iObjectHandles.Count();
-    PRINT1( _L( "MM MTP <> CCopyObject::CopyFolderL iNumberOfObjects = %d" ), iNumberOfObjects );
-
-    TRequestStatus* status = &iStatus;
-    User::RequestComplete( status, iStatus.Int() );
-    SetActive();
-
-    PRINT1( _L( "MM MTP <= CCopyObject::CopyFolderL handle = 0x%x" ), handle );
-    return handle;
-    }
-
-// -----------------------------------------------------------------------------
 // CCopyObject::CopyObjectL
 // Copy object operation
 // -----------------------------------------------------------------------------
 //
-void CCopyObject::CopyObjectL( TUint32& aNewHandle )
+void CCopyObject::CopyObjectL()
     {
     PRINT( _L( "MM MTP => CCopyObject::CopyObjectL" ) );
+
     TMTPResponseCode responseCode = EMTPRespCodeOK;
-    aNewHandle = KMTPHandleNone;
 
     GetParametersL();
 
     RBuf newObjectName;
+    newObjectName.CreateL( KMaxFileName );
     newObjectName.CleanupClosePushL(); // + newObjectName
-    newObjectName.CreateL( KMaxFileName );
     newObjectName = *iDest;
 
-    const TDesC& suid( iObjectInfo->DesC( CMTPObjectMetaData::ESuid ) );
+    const TDesC& suid( iSourceObject->DesC( CMTPObjectMetaData::ESuid ) );
     TParsePtrC fileNameParser( suid );
+    if ( ( newObjectName.Length() + fileNameParser.NameAndExt().Length() )
+        <= newObjectName.MaxLength() )
+        {
+        newObjectName.Append( fileNameParser.NameAndExt() );
+        responseCode = CanCopyObjectL( suid, newObjectName );
 
-    // Check if the object is a folder or a file.
-    TBool isFolder = EFalse;
-    User::LeaveIfError( BaflUtils::IsFolder( iFramework.Fs(), suid, isFolder ) );
-
-    if ( !isFolder )
-        {
-        if ( ( newObjectName.Length() + fileNameParser.NameAndExt().Length() ) <= newObjectName.MaxLength() )
+        TUint32 newHandle = KMTPHandleNone;
+        if ( responseCode == EMTPRespCodeOK )
             {
-            newObjectName.Append( fileNameParser.NameAndExt() );
-            }
-        responseCode = CanCopyObjectL( suid, newObjectName );
-        }
-    else // It is a folder.
-        {
-        TFileName rightMostFolderName;
-        User::LeaveIfError( BaflUtils::MostSignificantPartOfFullName( suid,
-            rightMostFolderName ) );
-        if ( ( newObjectName.Length() + rightMostFolderName.Length() + 1 ) <= newObjectName.MaxLength() )
-            {
-            newObjectName.Append( rightMostFolderName );
-            // Add backslash.
-            _LIT( KBackSlash, "\\" );
-            newObjectName.Append( KBackSlash );
+            newHandle = CopyFileL( newObjectName );
+            SendResponseL( EMTPRespCodeOK, 1, &newHandle );
+            PRINT2( _L( "MM MTP <= CCopyObject::CopyObjectL responseCode = 0x%x, aNewHandle = 0x%x" ),
+                responseCode,
+                newHandle );
             }
-        }
-
-    delete iNewRootFolder;
-    iNewRootFolder = NULL;
-    iNewRootFolder = newObjectName.AllocL();
-
-    if ( responseCode == EMTPRespCodeOK )
-        {
-        delete iFileMan;
-        iFileMan = NULL;
-        iFileMan = CFileMan::NewL( iFramework.Fs() );
-
-        if ( !isFolder ) // It is a file.
-            {
-            aNewHandle = CopyFileL( newObjectName );
-//            if ( responseCode == EMTPRespCodeOK  )
-            SendResponseL( EMTPRespCodeOK, 1, &aNewHandle );
-//            else
-//                SendResponseL( responseCode );
-            }
-        else // It is a folder.
-            {
-            delete iPathToCopy;
-            iPathToCopy = NULL;
-            iPathToCopy = suid.AllocL();
-            PRINT1( _L( "MM MTP <> CCopyObject::CopyObjectL iPathToCopy = %S" ), iPathToCopy );
-            aNewHandle = CopyFolderL( newObjectName );
-            }
+        else
+            SendResponseL( responseCode );
         }
     else
-        SendResponseL( responseCode );
+        // Destination is not appropriate for the full path name shouldn't be longer than 255
+        SendResponseL( EMTPRespCodeInvalidDataset );
 
     CleanupStack::PopAndDestroy( &newObjectName ); // - newObjectName
-    PRINT2( _L( "MM MTP <= CCopyObject::CopyObjectL responseCode = 0x%x, aNewHandle = 0x%x" ),
-            responseCode, aNewHandle );
     }
 
 // -----------------------------------------------------------------------------
@@ -337,37 +180,41 @@
 void CCopyObject::GetParametersL()
     {
     PRINT( _L( "MM MTP => CCopyObject::GetParametersL" ) );
+
     __ASSERT_DEBUG( iRequestChecker, Panic( EMmMTPDpRequestCheckNull ) );
 
     TUint32 objectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
     iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
-    TUint32 parentObjectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
-    PRINT3( _L( "MM MTP <> CCopyObject::GetParametersL Object Hanlde = 0x%x, StorageId = 0x%x, Parent Handle = 0x%x" ),
-            objectHandle, iStorageId, parentObjectHandle );
+    iNewParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
+    PRINT3( _L( "MM MTP <> CCopyObject::GetParametersL Object Handle = 0x%x, StorageId = 0x%x, Parent Handle = 0x%x" ),
+        objectHandle,
+        iStorageId,
+        iNewParentHandle );
 
     // not taking owernship
-    iObjectInfo = iRequestChecker->GetObjectInfo( objectHandle );
-    __ASSERT_DEBUG( iObjectInfo, Panic( EMmMTPDpObjectNull ) );
+    iSourceObject = iRequestChecker->GetObjectInfo( objectHandle );
+    __ASSERT_DEBUG( iSourceObject, Panic( EMmMTPDpObjectNull ) );
 
-    if ( parentObjectHandle == 0 )
+    if ( iNewParentHandle == KMTPHandleNone )
         {
         SetDefaultParentObjectL();
         }
     else
         {
-        CMTPObjectMetaData* parentObjectInfo = iRequestChecker->GetObjectInfo( parentObjectHandle );
-        __ASSERT_DEBUG( parentObjectInfo, Panic( EMmMTPDpObjectNull ) );
+        CMTPObjectMetaData* parentObject = iRequestChecker->GetObjectInfo( iNewParentHandle );
+        __ASSERT_DEBUG( parentObject, Panic( EMmMTPDpObjectNull ) );
+
         delete iDest;
         iDest = NULL;
-        iDest = parentObjectInfo->DesC( CMTPObjectMetaData::ESuid ).AllocL();
-        iNewParentHandle = parentObjectHandle;
+        iDest = parentObject->DesC( CMTPObjectMetaData::ESuid ).AllocL();
+        PRINT1( _L( "MM MTP <> CMoveObject::GetParametersL iDest = %S" ), iDest );
         }
     PRINT( _L( "MM MTP <= CCopyObject::GetParametersL" ) );
     }
 
 // -----------------------------------------------------------------------------
 // CCopyObject::SetDefaultParentObjectL
-// Get a default parent object, ff the request does not specify a parent object,
+// Set a default destination, if the request does not specify a parent object,
 // -----------------------------------------------------------------------------
 //
 void CCopyObject::SetDefaultParentObjectL()
@@ -376,11 +223,11 @@
 
     delete iDest;
     iDest = NULL;
-    iDest = ( iFramework.StorageMgr().StorageL( iStorageId ).DesC(
-                CMTPStorageMetaData::EStorageSuid ) ).AllocL();
-    PRINT1( _L( "MM MTP <> CCopyObject::SetDefaultParentObjectL Destination location is %S" ), iDest );
+    iDest = iFramework.StorageMgr().StorageL( iStorageId ).DesC( CMTPStorageMetaData::EStorageSuid ).AllocL();
+
     iNewParentHandle = KMTPHandleNoParent;
-    PRINT( _L( "MM MTP <= CCopyObject::SetDefaultParentObjectL" ) );
+
+    PRINT1( _L( "MM MTP <= CCopyObject::SetDefaultParentObjectL, iDest = %S" ), iDest );
     }
 
 // -----------------------------------------------------------------------------
@@ -392,17 +239,18 @@
     const TDesC& aNewName ) const
     {
     PRINT2( _L( "MM MTP => CCopyObject::CanCopyObjectL aOldName = %S, aNewName = %S" ),
-            &aOldName, &aNewName );
+        &aOldName,
+        &aNewName );
     TMTPResponseCode result = EMTPRespCodeOK;
 
     TEntry fileEntry;
     User::LeaveIfError( iFramework.Fs().Entry( aOldName, fileEntry ) );
-    TDriveNumber drive( static_cast<TDriveNumber>( iFramework.StorageMgr().DriveNumber( iStorageId ) ) );
+    TInt drive = iFramework.StorageMgr().DriveNumber( iStorageId );
     User::LeaveIfError( drive );
     TVolumeInfo volumeInfo;
     User::LeaveIfError( iFramework.Fs().Volume( volumeInfo, drive ) );
 
-    if ( volumeInfo.iFree < fileEntry.iSize )
+    if ( volumeInfo.iFree < fileEntry.FileSize() )
         {
         result = EMTPRespCodeStoreFull;
         }
@@ -433,7 +281,7 @@
 #endif
         }
     // This is used to keep the same behavior in mass storage and device file manager.
-    else if ( iObjectInfo->Uint( CMTPObjectMetaData::EFormatCode )
+    else if ( iSourceObject->Uint( CMTPObjectMetaData::EFormatCode )
         == EMTPFormatCodeAbstractAudioVideoPlaylist )
         {
         PRINT( _L( "MM MTP <> CCopyObject::CanCopyObjectL playlist file can't copy" ) );
@@ -445,38 +293,62 @@
     }
 
 // -----------------------------------------------------------------------------
+// CCopyObject::CopyFileL
+// A helper function of CopyFileL
+// -----------------------------------------------------------------------------
+//
+TUint32 CCopyObject::CopyFileL( const TDesC& aNewFileName )
+    {
+    PRINT( _L( "MM MTP => CCopyObject::CopyFileL" ) );
+
+    GetPreviousPropertiesL();
+
+    // TODO: Need rollback mechanism for consistant with image dp in fw.
+    // Not sure if it should be trap if something wrong with MPX db.
+    TPtrC oldFileName( iSourceObject->DesC( CMTPObjectMetaData::ESuid ) );
+    TUint32 handle = AddObjectToStoreL( oldFileName, aNewFileName );
+
+    // Only leave when getting proplist element from data received by fw.
+    // It should not happen after ReceiveDataL in which construction of proplist already succeed.
+    SetPreviousPropertiesL();
+
+    CFileMan* fileMan = CFileMan::NewL( iFramework.Fs() );
+    User::LeaveIfError( fileMan->Copy( oldFileName, aNewFileName ) );
+    delete fileMan;
+    fileMan = NULL;
+
+    PRINT( _L( "MM MTP <= CCopyObject::CopyFileL" ) );
+    return handle;
+    }
+
+// -----------------------------------------------------------------------------
 // CCopyObject::GetPreviousPropertiesL
 // Save the object properties before doing the copy
 // -----------------------------------------------------------------------------
 //
-void CCopyObject::GetPreviousPropertiesL( const CMTPObjectMetaData& aObject )
+void CCopyObject::GetPreviousPropertiesL()
     {
     PRINT( _L( "MM MTP => CCopyObject::GetPreviousPropertiesL" ) );
 
-    const TDesC& suid( aObject.DesC( CMTPObjectMetaData::ESuid ) );
-
-    User::LeaveIfError( iFramework.Fs().Modified( suid, iPreviousModifiedTime ) );
-
-    TUint formatCode = aObject.Uint( CMTPObjectMetaData::EFormatCode );
+    TUint formatCode = iSourceObject->Uint( CMTPObjectMetaData::EFormatCode );
     const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( formatCode );
     TInt count = properties->Count();
 
-    CMTPTypeString* textData = NULL;
     TInt err = KErrNone;
     TUint16 propCode;
-    TUint32 handle = aObject.Uint( CMTPObjectMetaData::EHandle ) ;
+    TUint32 handle = iSourceObject->Uint( CMTPObjectMetaData::EHandle );
 
-    if ( iPropertyElement )
+    if ( iPropertyElement != NULL )
         {
         delete iPropertyElement;
         iPropertyElement = NULL;
         }
-    
+
     for ( TInt i = 0; i < count; i++ )
         {
-        propCode = (*properties)[i];
+        propCode = ( *properties )[i];
 
-        switch( propCode )
+        switch ( propCode )
             {
             case EMTPObjectPropCodeStorageID:
             case EMTPObjectPropCodeObjectFormat:
@@ -485,53 +357,51 @@
             case EMTPObjectPropCodeObjectFileName:
             case EMTPObjectPropCodeParentObject:
             case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
-            case EMTPObjectPropCodeNonConsumable:
             case EMTPObjectPropCodeDateCreated:
             case EMTPObjectPropCodeDateModified:
                 break;
 
+            case EMTPObjectPropCodeNonConsumable:
+                iPropertyElement = &( iPropertyList->ReservePropElemL( handle, propCode ) );
+                iPropertyElement->SetUint8L( CMTPTypeObjectPropListElement::EValue,
+                    iSourceObject->Uint( CMTPObjectMetaData::ENonConsumable ) );
+                break;
+
             case EMTPObjectPropCodeName:
             case EMTPObjectPropCodeDateAdded:
-                if ( ( propCode == EMTPObjectPropCodeName )
-                   || ( ( !MmMtpDpUtility::IsVideoL( aObject.DesC( CMTPObjectMetaData::ESuid ), iFramework ) )
-                        && ( propCode == EMTPObjectPropCodeDateAdded ) ) )
-                    {
-                    textData = CMTPTypeString::NewLC(); // + textData
+            case EMTPObjectPropCodeAlbumArtist:
+                {
+                CMTPTypeString* textData = CMTPTypeString::NewLC(); // + textData
 
-                    TRAP( err, iDpConfig.GetWrapperL().GetObjectMetadataValueL( propCode,
-                        *textData,
-                        aObject ) );
+                TRAP( err, iDpConfig.GetWrapperL().GetObjectMetadataValueL( propCode,
+                    *textData,
+                    *iSourceObject ) );
 
-                    PRINT1( _L( "MM MTP <> CCopyObject::GetPreviousPropertiesL::ServiceSpecificObjectPropertyL err = %d" ), err );
+                PRINT1( _L( "MM MTP <> CCopyObject::GetPreviousPropertiesL err = %d" ), err );
 
-                    if ( err == KErrNone )
-                        {
-                        iPropertyElement = &(iPropertyList->ReservePropElemL(handle, propCode));
-                        iPropertyElement->SetStringL(CMTPTypeObjectPropListElement::EValue, textData->StringChars());
-//                        iPropertyElement = CMTPTypeObjectPropListElement::NewL(
-//                                handle, propCode, *textData );
-                        }
-                    else if ( err == KErrNotFound )
-                        {
-                        iPropertyElement = NULL;
-                        }
-                    else
-                        {
-                        User::Leave( err );
-                        }
+                if ( err == KErrNone )
+                    {
+                    iPropertyElement = &( iPropertyList->ReservePropElemL( handle, propCode ) );
+                    iPropertyElement->SetStringL( CMTPTypeObjectPropListElement::EValue,
+                        textData->StringChars() );
+                    }
+                else
+                    {
+                    iPropertyElement = NULL;
+                    }
 
-                    CleanupStack::PopAndDestroy( textData ); // - textData
-                    }
+                CleanupStack::PopAndDestroy( textData ); // - textData
+                }
                 break;
 
             default:
                 {
-                ServiceGetSpecificObjectPropertyL( propCode, handle, aObject );
+                ServiceGetSpecificObjectPropertyL( propCode, handle, *iSourceObject );
                 }
                 break;
             }
 
-        if ( iPropertyElement )
+        if ( iPropertyElement != NULL )
             {
             iPropertyList->CommitPropElemL( *iPropertyElement );
             iPropertyElement = NULL;
@@ -542,78 +412,29 @@
     }
 
 // -----------------------------------------------------------------------------
-// CCopyObject::ServiceMetaDataToWrapper
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C TMTPResponseCode CCopyObject::ServiceMetaDataToWrapper(
-    const TUint16 aPropCode,
-    MMTPType& aNewData,
-    const CMTPObjectMetaData& aObject )
-    {
-    TMTPResponseCode resCode = EMTPRespCodeOK;
-
-    TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode,
-        aNewData,
-        aObject ) );
-
-    PRINT1( _L("MM MTP <> CCopyObject::ServiceMetaDataToWrapper err = %d"), err);
-
-    if ( err == KErrNone )
-        {
-        resCode = EMTPRespCodeOK;
-        }
-    else if ( err == KErrTooBig )
-        // according to the codes of S60
-        {
-        resCode = EMTPRespCodeInvalidDataset;
-        }
-    else if ( err == KErrPermissionDenied )
-        {
-        resCode = EMTPRespCodeAccessDenied;
-        }
-    else if ( err == KErrNotFound )
-        {
-        if ( MmMtpDpUtility::HasMetadata( aObject.Uint( CMTPObjectMetaData::EFormatCode ) ) )
-            resCode = EMTPRespCodeAccessDenied;
-        else
-            resCode = EMTPRespCodeOK;
-        }
-    else
-        {
-        resCode = EMTPRespCodeGeneralError;
-        }
-
-    PRINT1( _L("MM MTP <= CCopyObject::ServiceMetaDataToWrapper resCode = 0x%x"), resCode);
-
-    return resCode;
-    }
-
-// -----------------------------------------------------------------------------
 // CCopyObject::SetPreviousPropertiesL
 // Set the object properties after doing the copy
 // -----------------------------------------------------------------------------
 //
-void CCopyObject::SetPreviousPropertiesL( const CMTPObjectMetaData& aObject )
+void CCopyObject::SetPreviousPropertiesL()
     {
     PRINT( _L( "MM MTP => CCopyObject::SetPreviousPropertiesL" ) );
-    const TInt count( iPropertyList->NumberOfElements() );
-    PRINT1( _L( "MM MTP <> CCopyObject::SetPreviousPropertiesL count = %d" ), count );
+
     TMTPResponseCode respcode = EMTPRespCodeOK;
-    CMTPTypeString* stringData = NULL;
+
     iPropertyList->ResetCursor();
+    const TInt count = iPropertyList->NumberOfElements();
     for ( TInt i = 0; i < count; i++ )
         {
         CMTPTypeObjectPropListElement& element = iPropertyList->GetNextElementL();
 
-        TUint32 handle = element.Uint32L(
-                CMTPTypeObjectPropListElement::EObjectHandle );
-        TUint16 propertyCode = element.Uint16L(
-                CMTPTypeObjectPropListElement::EPropertyCode );
-        TUint16 dataType = element.Uint16L(
-                CMTPTypeObjectPropListElement::EDatatype );
+        TUint32 handle = element.Uint32L( CMTPTypeObjectPropListElement::EObjectHandle );
+        TUint16 propertyCode = element.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode );
+        TUint16 dataType = element.Uint16L( CMTPTypeObjectPropListElement::EDatatype );
         PRINT3( _L( "MM MTP <> CCopyObject::SetPreviousPropertiesL = 0x%x, propertyCode = 0x%x, dataType = 0x%x" ),
-          handle, propertyCode, dataType );
+            handle,
+            propertyCode,
+            dataType );
 
         switch ( propertyCode )
             {
@@ -624,21 +445,29 @@
             case EMTPObjectPropCodeObjectFileName:
             case EMTPObjectPropCodeParentObject:
             case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
-            case EMTPObjectPropCodeNonConsumable:
             case EMTPObjectPropCodeDateCreated:
             case EMTPObjectPropCodeDateModified:
             case EMTPObjectPropCodeDateAdded:
                 break;
 
+            case EMTPObjectPropCodeNonConsumable:
+                iTargetObject->SetUint( CMTPObjectMetaData::ENonConsumable,
+                    element.Uint8L( CMTPTypeObjectPropListElement::EValue ) );
+                // TODO: need to reconsider,
+                // should wait all property setting finished then insert object, or not?
+                // need to investigate if it will affect performance result
+                iFramework.ObjectMgr().ModifyObjectL( *iTargetObject );
+                break;
+
             case EMTPObjectPropCodeName:
+            case EMTPObjectPropCodeAlbumArtist:
                 {
-                stringData = CMTPTypeString::NewLC(
-                    element.StringL(
-                    CMTPTypeObjectPropListElement::EValue)); // + stringData
+                CMTPTypeString *stringData = CMTPTypeString::NewLC( element.StringL( CMTPTypeObjectPropListElement::EValue ) ); // + stringData
 
-                respcode = ServiceMetaDataToWrapper( propertyCode,
+                respcode = iDpConfig.PropSettingUtility()->SetMetaDataToWrapper( iDpConfig,
+                    propertyCode,
                     *stringData,
-                    aObject );
+                    *iTargetObject );
 
                 CleanupStack::PopAndDestroy( stringData ); // - stringData
                 }
@@ -646,17 +475,19 @@
 
             default:
                 {
-                respcode = ServiceSetSpecificObjectPropertyL( propertyCode,
-                        aObject,
-                        element );
+                respcode = iDpConfig.PropSettingUtility()->SetSpecificObjectPropertyL( iDpConfig,
+                    propertyCode,
+                    *iTargetObject,
+                    element );
                 }
                 break;
             }
         } // end of for loop
 
-    if( respcode == EMTPRespCodeOK )
+    // ignore errors
+    if ( respcode == EMTPRespCodeOK )
         {
-        // do nothing, ignore warning
+        // do nothing, just to get rid of build warning
         }
 
     PRINT1( _L( "MM MTP <= CCopyObject::SetPreviousPropertiesL respcode = 0x%x" ), respcode );
@@ -667,168 +498,42 @@
 // Update object info in the database
 // -----------------------------------------------------------------------------
 //
-TUint32 CCopyObject::UpdateObjectInfoL( const TDesC& aOldObjectName, const TDesC& aNewObjectName )
+TUint32 CCopyObject::AddObjectToStoreL( const TDesC& aOldObjectName,
+    const TDesC& aNewObjectName )
     {
-    PRINT2( _L( "MM MTP => CCopyObject::UpdateObjectInfoL aOldObjectName = %S, aNewObjectName = %S" ),
-            &aOldObjectName, &aNewObjectName );
-    // We should not modify this object's handle, so just get a "copy".
-    CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
-    const TMTPTypeUint32 objectHandle( iObjectInfo->Uint( CMTPObjectMetaData::EHandle ) );
-    if ( iFramework.ObjectMgr().ObjectL( objectHandle, *objectInfo) )
+    PRINT2( _L( "MM MTP => CCopyObject::AddObjectToStoreL aOldObjectName = %S, aNewObjectName = %S" ),
+        &aOldObjectName,
+        &aNewObjectName );
+
+    iTargetObject = CMTPObjectMetaData::NewL();
+
+    // 1. Add new object into objectMgr db
+    iTargetObject->SetUint( CMTPObjectMetaData::EDataProviderId, iSourceObject->Uint( CMTPObjectMetaData::EDataProviderId ) );
+    TUint formatCode = iSourceObject->Uint( CMTPObjectMetaData::EFormatCode );
+    iTargetObject->SetUint( CMTPObjectMetaData::EFormatCode, formatCode );
+    TUint subFormatCode = iSourceObject->Uint( CMTPObjectMetaData::EFormatSubCode );
+    iTargetObject->SetUint( CMTPObjectMetaData::EFormatSubCode, subFormatCode );
+    iTargetObject->SetUint( CMTPObjectMetaData::EParentHandle, iNewParentHandle );
+    iTargetObject->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
+    iTargetObject->SetDesCL( CMTPObjectMetaData::ESuid, aNewObjectName );
+    iFramework.ObjectMgr().InsertObjectL( *iTargetObject );
+
+    // 2. Add new object into MPX db
+    iDpConfig.GetWrapperL().AddObjectL( *iTargetObject );
+
+    // 3. Set references into references db
+    if ( formatCode == EMTPFormatCodeM3UPlaylist )
         {
-        objectInfo->SetDesCL( CMTPObjectMetaData::ESuid, aNewObjectName );
-        objectInfo->SetUint( CMTPObjectMetaData::EParentHandle,
-                iNewParentHandle );
-        // Modify storage Id.
-        objectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
-        iFramework.ObjectMgr().InsertObjectL( *objectInfo );
-        }
-    else
-        {
-        User::Leave( KErrCorrupt );
+        MMTPReferenceMgr& referenceMgr = iFramework.ReferenceMgr();
+        CDesCArray* references = referenceMgr.ReferencesLC( aOldObjectName ); // + references
+        referenceMgr.SetReferencesL( aNewObjectName, *references );
+        CleanupStack::PopAndDestroy( references ); // - references
         }
 
-    TUint32 handle = objectInfo->Uint( CMTPObjectMetaData::EHandle );
-    PRINT1( _L( "MM MTP <> CCopyObject::UpdateObjectInfoL handle = 0x%x" ), handle );
-    SetPropertiesL( aOldObjectName, aNewObjectName, *objectInfo );
-    CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
-    PRINT( _L( "MM MTP <= CCopyObject::UpdateObjectInfoL" ) );
+    TUint32 handle = iTargetObject->Uint( CMTPObjectMetaData::EHandle );
+
+    PRINT1( _L( "MM MTP <= CCopyObject::AddObjectToStoreL handle = 0x%x" ), handle );
     return handle;
     }
 
-// -----------------------------------------------------------------------------
-// CCopyObject::CopyAndUpdateL
-// Move a single object and update the database
-// -----------------------------------------------------------------------------
-//
-void CCopyObject::CopyAndUpdateL( TUint32 aObjectHandle )
-    {
-    PRINT1( _L( "MM MTP => CopyObject::CopyAndUpdateL aObjectHanlde = 0x%x" ), aObjectHandle );
-    CMTPObjectMetaData* objectInfo = CMTPObjectMetaData::NewLC(); // + objectInfo
-
-    if ( iFramework.ObjectMgr().ObjectL( aObjectHandle, *objectInfo ) )
-        {
-        // This is used to keep the same behavior in mass storage and device file manager.
-        if ( objectInfo->Uint( CMTPObjectMetaData::EFormatCode )
-            == EMTPFormatCodeAbstractAudioVideoPlaylist )
-            {
-            PRINT( _L( "MM MTP <> CopyObject::CopyAndUpdateL Playlist file don't to be copieds" ) );
-            CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
-            return;
-            }
-
-        RBuf fileName; // This is the source object name.
-        fileName.CleanupClosePushL(); // + fileName
-        fileName.CreateL( KMaxFileName );
-
-        RBuf oldFileName;
-        oldFileName.CleanupClosePushL(); // + oldFileName
-        oldFileName.CreateL( KMaxFileName );
-
-        RBuf rightPartName;
-        rightPartName.CleanupClosePushL(); // + rightPartName
-        rightPartName.CreateL( KMaxFileName );
-
-        fileName = objectInfo->DesC( CMTPObjectMetaData::ESuid );
-        oldFileName = fileName;
-
-        rightPartName = fileName.Right( fileName.Length()
-            - iPathToCopy->Length() );
-
-        if ( ( iNewRootFolder->Length() + rightPartName.Length() ) > fileName.MaxLength() )
-            {
-            User::Leave( KErrCorrupt );
-            }
-
-        fileName.Zero();
-        fileName.Append( *iNewRootFolder );
-        fileName.Append( rightPartName );
-        PRINT1( _L( "MM MTP <> CopyAndUpdateL fileName = %S" ), &fileName );
-
-        if ( objectInfo->Uint( CMTPObjectMetaData::EDataProviderId )
-            == iFramework.DataProviderId() )
-            {
-            // should copy before the set metadata DB
-            GetPreviousPropertiesL( *objectInfo );
-            TInt err = iFileMan->Copy( oldFileName, fileName );
-            PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL err = %d" ), err );
-            User::LeaveIfError( err );
-            User::LeaveIfError( iFramework.Fs().SetModified( fileName,
-                iPreviousModifiedTime ) );
-
-            // Modify Suid
-            objectInfo->SetDesCL( CMTPObjectMetaData::ESuid, fileName );
-
-            // Modify parentHandle
-            TParsePtrC parentSuid( fileName );
-            PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL parentSuid = %S" ), &(parentSuid.DriveAndPath()) );
-
-            TUint32 parentHandle = iFramework.ObjectMgr().HandleL( parentSuid.DriveAndPath() );
-            objectInfo->SetUint( CMTPObjectMetaData::EParentHandle, parentHandle );
-            PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL parentHandle = 0x%x" ), parentHandle );
-
-            // Modify storage Id.
-            objectInfo->SetUint( CMTPObjectMetaData::EStorageId, iStorageId );
-            TRAP( err, iFramework.ObjectMgr().InsertObjectL( *objectInfo ) );
-            if ( err != KErrNone )
-                PRINT1( _L( "MM MTP <> CCopyObject::CopyAndUpdateL err = %d" ), err );
-            // Set the properties of the new object
-            SetPropertiesL( oldFileName, fileName, *objectInfo );
-            }
-        // Else this is not the owner of this object, so don't update the object store.
-
-        CleanupStack::PopAndDestroy( &rightPartName ); // - rightPartName
-        CleanupStack::PopAndDestroy( &oldFileName ); // - oldFileName
-        CleanupStack::PopAndDestroy( &fileName ); // - fileName
-        }
-    else
-        {
-        User::Leave( KErrCorrupt );
-        }
-
-    CleanupStack::PopAndDestroy( objectInfo ); // - objectInfo
-
-    PRINT( _L( "MM MTP <= CopyObject::CopyAndUpdateL" ) );
-    }
-
-// -----------------------------------------------------------------------------
-// CCopyObject::SetPropertiesL
-// Set the object properties in the object property store
-// -----------------------------------------------------------------------------
-//
-void CCopyObject::SetPropertiesL( const TDesC& aOldFileName,
-        const TDesC& aNewFileName,
-        const CMTPObjectMetaData& aObject )
-    {
-    PRINT( _L( "MM MTP => CCopyObject::SetPropertiesL" ) );
-    // won't leave with KErrAlreadyExist
-    iDpConfig.GetWrapperL().AddObjectL( aNewFileName );
-
-    TUint formatCode = aObject.Uint( CMTPObjectMetaData::EFormatCode );
-    if ( formatCode == EMTPFormatCodeM3UPlaylist )
-        {
-        MMTPReferenceMgr& referenceMgr = iFramework.ReferenceMgr();
-        CDesCArray* references = referenceMgr.ReferencesLC( aOldFileName ); // + references
-        referenceMgr.SetReferencesL( aNewFileName, *references );
-        CleanupStack::PopAndDestroy( references ); // - references
-        }
-
-    SetPreviousPropertiesL( aObject );
-    PRINT( _L( "MM MTP <= CCopyObject::SetPropertiesL" ) );
-    }
-
-// -----------------------------------------------------------------------------
-// CCopyObject::RunError
-//
-// -----------------------------------------------------------------------------
-//
-EXPORT_C TInt CCopyObject::RunError( TInt aError )
-    {
-    if ( aError != KErrNone )
-        PRINT1( _L( "MM MTP <> CCopyObject::RunError aError = %d" ), aError );
-
-    TRAP_IGNORE( SendResponseL( EMTPRespCodeGeneralError ) );
-    return KErrNone;
-    }
-
 // end of file