mtpdataproviders/mtpimagedp/src/cmtpimagedp.cpp
author hgs
Thu, 04 Nov 2010 15:31:42 +0800
changeset 60 841f70763fbe
parent 49 c20dd21d1eb4
permissions -rw-r--r--
201044_04

// 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:
//

/**
 @file
 @internalTechnology
*/

#include <e32cmn.h>
#include <centralrepository.h>
#include <mtp/tmtptyperequest.h>
#include <mtp/cmtpstoragemetadata.h>
#include <mtp/cmtpobjectmetadata.h>
#include <mtp/mmtpconnection.h>
#include <mtp/mmtpdataproviderframework.h>
#include <mtp/mtpdataproviderapitypes.h>
#include <mtp/mtpprotocolconstants.h>
#include <mtp/mmtpobjectmgr.h>
#include <mtp/mmtpstoragemgr.h>
#include <mtp/cmtpobjectmetadata.h>
#include <mtp/tmtptypeevent.h>

#include "cmtpimagedp.h"
#include "mtpimagedpconst.h"
#include "mtpimagedppanic.h"
#include "cmtprequestprocessor.h"
#include "mtpimagedprequestprocessor.h"
#include "cmtpimagedpthumbnailcreator.h"
#include "mtpimagedputilits.h"
#include "cmtpimagedpmdeobserver.h"
#include "cmtpimagedprenameobject.h"
#include "cmtpimagedpnewpicturesnotifier.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmtpimagedpTraces.h"
#endif


static const TInt KArrayGranularity = 3;
static const TInt KDeleteObjectGranularity = 2;

//used by hashmap & hashset class
LOCAL_C TUint32 TBuf16Hash(const TBuf<KMaxExtNameLength>& aPtr)
    {
    return DefaultHash::Des16(aPtr);
    }

LOCAL_C TBool TBuf16Ident(const TBuf<KMaxExtNameLength>& aL, const TBuf<KMaxExtNameLength>& aR)
    {
    return DefaultIdentity::Des16(aL, aR);
    }

/**
 Image data provider factory method.
 @return A pointer to a Image data provider object. Ownership is transfered.
 @leave One of the system wide error codes, if a processing failure occurs.
*/
TAny* CMTPImageDataProvider::NewL(TAny* aParams)
    {
    CMTPImageDataProvider* self = new (ELeave) CMTPImageDataProvider(aParams);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

/**
 Standard C++ constructor
 
 @param aParams  pointer to MMTPDataProviderFramework
*/
CMTPImageDataProvider::CMTPImageDataProvider(TAny* aParams) :
    CMTPDataProviderPlugin(aParams),
    iActiveProcessors(KArrayGranularity),
    iFormatMappings(&TBuf16Hash, &TBuf16Ident),
    iMimeMappings(&TBuf16Hash, &TBuf16Ident),
    iActiveProcessor(-1),
    iEnumerated(EFalse),
	iDeleteObjectsArray(KDeleteObjectGranularity)
    {
    }

/**
Second-phase construction
*/
void CMTPImageDataProvider::ConstructL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_CONSTRUCTL_ENTRY );
    
    iNewPicNotifier = CMTPImageDpNewPicturesNotifier::NewL();
    
    //Setup central repository connection
    const TUint32 KUidMTPImageRepositoryValue(0x2001FCA2);
    const TUid KUidMTPImageRepository = {KUidMTPImageRepositoryValue};
    iRepository = CRepository::NewL(KUidMTPImageRepository);    
    
    //Initialize hash map of extention to format code
    TInt count(sizeof(KMTPValidCodeExtensionMappings) / sizeof(KMTPValidCodeExtensionMappings[0]));
    for(TInt i(0); i<count; i++)
        {
        iFormatMappings.Insert(KMTPValidCodeExtensionMappings[i].iExtension, KMTPValidCodeExtensionMappings[i].iFormatCode);
        }    
    
    //Initialize hash map of extension to mime type
    count = sizeof(KMTPExtensionMimeTypeMappings) / sizeof(KMTPExtensionMimeTypeMappings[0]);
    for(TInt i(0); i<count; i++)
        {
        iMimeMappings.Insert(KMTPExtensionMimeTypeMappings[i].iExtension, KMTPExtensionMimeTypeMappings[i].iMimeType);
        }     
    
    //Define RProperty of new pictures for status data provider
	RProcess process;
	TUid tSid = process.SecureId();
    _LIT_SECURITY_POLICY_PASS(KAllowReadAll);
    TInt error = RProperty::Define(tSid, KMTPNewPicKey, RProperty::EInt, KAllowReadAll, KAllowReadAll);
    if (error != KErrNone && error != KErrAlreadyExists)
        {
        LEAVEIFERROR(error,
                OstTrace1( TRACE_ERROR, DUP1_CMTPIMAGEDATAPROVIDER_CONSTRUCTL, 
                        "RProperty define error:%d", error ));
                
        }    
    
    iEnumerationNotified = ETrue;
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_CONSTRUCTL_EXIT );
    }

/**
 Destructor
*/
CMTPImageDataProvider::~CMTPImageDataProvider()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_CMTPIMAGEDATAPROVIDER_DES_ENTRY );
    
    // delete all processor instances
    TUint count(iActiveProcessors.Count());
    while (count--)
        {
        iActiveProcessors[count]->Release();
        }
    iActiveProcessors.Close();
     
    // image dp unsubscribe from MDS
    if(iMdeObserver)
        {
        TRAP_IGNORE(iMdeObserver->UnsubscribeForChangeNotificationL());
        delete iMdeObserver;
        }        
    delete iThumbnailManager;
    delete iPropertyMgr;       
    delete iRepository;   
    delete iRenameObject;
    delete iNewPicNotifier;
    
    iFormatMappings.Close();
    iMimeMappings.Close();
    
    //Try to delete objects in array
    HandleDeleteObjectsArray();
    iDeleteObjectsArray.ResetAndDestroy();
    iNewPicHandles.Reset();

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_CMTPIMAGEDATAPROVIDER_DES_EXIT );
    }

void CMTPImageDataProvider::Cancel()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_CANCEL_ENTRY );
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_CANCEL_EXIT );
    }

/**
 Process the event from initiator
 
 @param aEvent       The event to be processed
 @param aConnection  The connection from which the event comes
*/
void CMTPImageDataProvider::ProcessEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_PROCESSEVENTL_ENTRY );
    
    //Try to delete objects in array
    HandleDeleteObjectsArray();
    
    TInt idx(LocateRequestProcessorL(aEvent, aConnection));
    
    if (idx != KErrNotFound)
        {
        iActiveProcessors[idx]->HandleEventL(aEvent);
        }

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_PROCESSEVENTL_EXIT );
    }

/**
Process the notification from framework
@param aNotification  The notification to be processed
@param aParams        Notification parmenter
*/
void CMTPImageDataProvider::ProcessNotificationL(TMTPNotification aNotification, const TAny* aParams)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_PROCESSNOTIFICATIONL_ENTRY );

    switch (aNotification)
        {
    case EMTPSessionClosed:
        SessionClosedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams));
        break;
        
    case EMTPSessionOpened:
        SessionOpenedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams));
        break;
        
    case EMTPRenameObject:
        RenameObjectL(*reinterpret_cast<const TMTPNotificationParamsHandle*>(aParams));
        break;
        
    default:
        // Ignore all other notifications.
        break;
        }

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_PROCESSNOTIFICATIONL_EXIT );
    }

/**
 Process the request from initiator
 
 @param aPhase       The request transaction phase
 @param aRequest     The request to be processed
 @param aConnection  The connection from which the request comes
*/   
void CMTPImageDataProvider::ProcessRequestPhaseL(TMTPTransactionPhase aPhase, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
    {    
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_PROCESSREQUESTPHASEL_ENTRY );
    
    //Try to handle objects which need to be deleted
    HandleDeleteObjectsArray();
    
    TInt idx(LocateRequestProcessorL(aRequest, aConnection));
    __ASSERT_DEBUG((idx != KErrNotFound), Panic(EMTPImageDpNoMatchingProcessor));
    MMTPRequestProcessor* processor(iActiveProcessors[idx]);
    iActiveProcessor = idx;
    iActiveProcessorRemoved = EFalse;    
    TBool result(processor->HandleRequestL(aRequest, aPhase));
    if (iActiveProcessorRemoved)
        {
        processor->Release(); // destroy the processor
        }    
    else if (result)    //destroy the processor
        {
        processor->Release();
        iActiveProcessors.Remove(idx);
        }
 
    iActiveProcessor = -1;
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_PROCESSREQUESTPHASEL_EXIT );
    }

/**
 Starts the enumeration of the image dp
*/
void CMTPImageDataProvider::StartObjectEnumerationL(TUint32 aStorageId, TBool /*aPersistentFullEnumeration*/)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_STARTOBJECTENUMERATIONL_ENTRY );
    
    TBool isComplete = ETrue;
    iEnumerationNotified = EFalse;

    if (aStorageId == KMTPStorageAll)
        {
        /*
         * framework notify data provider to enumerate
         * 
         */
        if (iPropertyMgr == NULL)
            {
            iPropertyMgr = CMTPImageDpObjectPropertyMgr::NewL(Framework(), *this);
            isComplete = EFalse;
            }
  
        iEnumerated = ETrue;
        }

    if (isComplete)
        {
        NotifyEnumerationCompleteL(aStorageId, KErrNone);
        }
    
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_STARTOBJECTENUMERATIONL_EXIT );
    }


/**
Starts enumerate imagedp storage, just declare complete
*/
void CMTPImageDataProvider::StartStorageEnumerationL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_STARTSTORAGEENUMERATIONL_ENTRY );
    NotifyStorageEnumerationCompleteL();   
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_STARTSTORAGEENUMERATIONL_EXIT );
    }

/**
Defines the supported operations and formats of the data provider

@param aCategory Defines what MTP is quering the DP about
@param aArray Supported() edits array to append supported features
*/
void CMTPImageDataProvider::Supported(TMTPSupportCategory aCategory, RArray<TUint>& aArray) const
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_SUPPORTED_ENTRY );

    switch (aCategory) 
        {        
    case EEvents:
        {
        TInt count(sizeof(KMTPImageDpSupportedEvents) / sizeof(KMTPImageDpSupportedEvents[0]));
        for (TInt i(0); (i < count); i++)
            {
            aArray.Append(KMTPImageDpSupportedEvents[i]);
            OstTrace1( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_SUPPORTED, 
                    "   CMTPImageDataProvider::Supported Events %d added", KMTPImageDpSupportedEvents[i] );
            }  
        }
        break;
    case EObjectPlaybackFormats: // formats that can be placed on the device
	/*intentional fall through*/ 
    case EObjectCaptureFormats: // formats the device generates
        {
        TInt count(sizeof(KMTPValidCodeExtensionMappings) / sizeof(KMTPValidCodeExtensionMappings[0]));
        for(TInt i(0); (i < count); i++)
            {
            OstTrace1( TRACE_NORMAL, DUP1_CMTPIMAGEDATAPROVIDER_SUPPORTED, 
                    "   CMTPImageDataProvider::Supported we have formatCode %d", KMTPValidCodeExtensionMappings[i].iFormatCode  );
            if(aArray.Find(KMTPValidCodeExtensionMappings[i].iFormatCode)==KErrNotFound) // KMTPValidCodeExtensionMappings may contain format code more than once
                {
                aArray.Append(KMTPValidCodeExtensionMappings[i].iFormatCode);
                OstTrace1( TRACE_NORMAL, DUP2_CMTPIMAGEDATAPROVIDER_SUPPORTED, 
                        "   CMTPImageDataProvider::Supported formatCode %d added", KMTPValidCodeExtensionMappings[i].iFormatCode );
                }
            }
        }
        break;
    case EObjectProperties:
        {
        TInt count(sizeof(KMTPImageDpSupportedProperties) / sizeof(KMTPImageDpSupportedProperties[0]));
        for (TInt i(0); (i < count); i++)
            {
            aArray.Append(KMTPImageDpSupportedProperties[i]);
            OstTrace1( TRACE_NORMAL, DUP3_CMTPIMAGEDATAPROVIDER_SUPPORTED, 
                    "   CMTPImageDataProvider::Supported property %d added", KMTPImageDpSupportedProperties[i] );
            
            }   
        }
        break; 

    case EOperations:
        {
        TInt count(sizeof(KMTPImageDpSupportedOperations) / sizeof(KMTPImageDpSupportedOperations[0]));
        for (TInt i(0); (i < count); i++)
            {
            aArray.Append(KMTPImageDpSupportedOperations[i]);
            OstTrace1( TRACE_NORMAL, DUP4_CMTPIMAGEDATAPROVIDER_SUPPORTED, 
                    "   CMTPImageDataProvider::Supported operation %d added", KMTPImageDpSupportedOperations[i] );
            }   
        }
        break;  

    case EStorageSystemTypes:
        aArray.Append(CMTPStorageMetaData::ESystemTypeDefaultFileSystem);
        break; 

    default:    
        // Unrecognised category, leave aArray unmodified.
        break;
        }

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_SUPPORTED_EXIT );
    }

/**
Defines the supported vendor extension info of the data provider

@param aCategory Defines what MTP is quering the DP about
@param aStrings Supported() edits array to append supported vendor info
*/
void CMTPImageDataProvider::SupportedL(TMTPSupportCategory aCategory, CDesCArray& aStrings) const
    {
    switch (aCategory) 
        {
    case EFolderExclusionSets:
        {
        //do nothing
        }
        break;
        
    case EFormatExtensionSets:
        {
        _LIT(KFormatExtensionJpg, "0x3801:jpg:::3");//3 means file dp will enumerate all image files instead of image dp.
        aStrings.AppendL(KFormatExtensionJpg);
        _LIT(KFormatExtensionJpe, "0x3801:jpe:::3");
        aStrings.AppendL(KFormatExtensionJpe);
        _LIT(KFormatExtensionJpeg, "0x3801:jpeg:::3");
        aStrings.AppendL(KFormatExtensionJpeg);
        
        /*
         * bmp files
         */
        _LIT(KFormatExtensionBmp, "0x3804:bmp:::3");
        aStrings.AppendL(KFormatExtensionBmp);
        
        /*
         * gif files
         */
        _LIT(KFormatExtensionGif, "0x3807:gif:::3");
        aStrings.AppendL(KFormatExtensionGif);
        
        /*
         * png files
         */
        _LIT(KFormatExtensionPng, "0x380B:png:::3");
        aStrings.AppendL(KFormatExtensionPng);
        
        /*
         * tif, tiff files
         */
        /*
        _LIT(KFormatExtensionTif, "0x380D:tif::3");
        aStrings.AppendL(KFormatExtensionTif);
        _LIT(KFormatExtensionTiff, "0x380D:tiff::3");
        aStrings.AppendL(KFormatExtensionTiff);
        */                 
        }
        break;
        
    default:
        // Unrecognised category, leave aArray unmodified.
        break;
        }
    }

/**
Notify framework the image dp has completed enumeration
*/
void CMTPImageDataProvider::NotifyStorageEnumerationCompleteL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_NOTIFYSTORAGEENUMERATIONCOMPLETEL_ENTRY );   
    Framework().StorageEnumerationCompleteL();          
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_NOTIFYSTORAGEENUMERATIONCOMPLETEL_EXIT );
    }

CMTPImageDpThumbnailCreator* CMTPImageDataProvider::ThumbnailManager()
    {
    if(NULL == iThumbnailManager)
        {
        TRAP_IGNORE(iThumbnailManager = CMTPImageDpThumbnailCreator::NewL(*this));
        }
    return iThumbnailManager;
    }

CMTPImageDpObjectPropertyMgr& CMTPImageDataProvider::PropertyMgr()const
	{
	__ASSERT_DEBUG(iPropertyMgr, User::Invariant());
	return *iPropertyMgr;	
	}

CRepository& CMTPImageDataProvider::Repository() const
    {
    __ASSERT_DEBUG(iRepository, User::Invariant());
    return *iRepository;
    }

// --------------------------------------------------------------------------
// 
// --------------------------------------------------------------------------
//
#ifdef OST_TRACE_COMPILER_IN_USE  
void CMTPImageDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt aError)
#else
void CMTPImageDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt /*aError*/)
#endif // OST_TRACE_COMPILER_IN_USE
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_NOTIFYENUMERATIONCOMPLETEL_ENTRY );
    OstTraceExt2( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_NOTIFYENUMERATIONCOMPLETEL, 
            "Enumeration of storage 0x%08X completed with error status %d", aStorageId, (TInt32)aError );

    if (!iEnumerationNotified)
        {
        iEnumerationNotified = ETrue;
        Framework().ObjectEnumerationCompleteL(aStorageId);
        }
    
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_NOTIFYENUMERATIONCOMPLETEL_EXIT );
    }

/**
Find or create a request processor that can process the request

@param aRequest    The request to be processed
@param aConnection The connection from which the request comes

@return the index of the found/created request processor
*/
TInt CMTPImageDataProvider::LocateRequestProcessorL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_LOCATEREQUESTPROCESSORL_ENTRY );     
    
    TInt idx(KErrNotFound);
    TInt count(iActiveProcessors.Count());
    for (TInt i(0); (i < count); i++)
        {
        if (iActiveProcessors[i]->Match(aRequest, aConnection))
            {
            idx = i;
            break;
            }
        }
        
    if (idx == KErrNotFound)
        {
        MMTPRequestProcessor* processor = MTPImageDpProcessor::CreateL(Framework(), aRequest, aConnection,*this);
        CleanupReleasePushL(*processor);
        iActiveProcessors.AppendL(processor);
        CleanupStack::Pop();
        idx = count;
        }

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_LOCATEREQUESTPROCESSORL_EXIT );
    return idx;
    }

/**
Find or create a request processor that can process the event

@param aEvent    The event to be processed
@param aConnection The connection from which the request comes

@return the index of the found/created request processor
*/
TInt CMTPImageDataProvider::LocateRequestProcessorL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
    {
    OstTraceFunctionEntry0( DUP1_CMTPIMAGEDATAPROVIDER_LOCATEREQUESTPROCESSORL_ENTRY );
        
    TInt idx(KErrNotFound);
    TInt count(iActiveProcessors.Count());
    for (TInt i(0); (i < count); i++)
        {
        if (iActiveProcessors[i]->Match(aEvent, aConnection))
            {
            idx = i;
            break;
            }
        }    

    OstTraceFunctionExit0( DUP1_CMTPIMAGEDATAPROVIDER_LOCATEREQUESTPROCESSORL_EXIT );
    return idx;
    }

/**
 Notify the data provider that the session has been closed

 @param aSessionId    The session Id closed
 @param aConnection   The connection of the sesssion
*/
void CMTPImageDataProvider::SessionClosedL(const TMTPNotificationParamsSessionChange& aSession)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_SESSIONCLOSEDL_ENTRY );
    OstTrace1( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_SESSIONCLOSEDL, "SessionID = %d", aSession.iMTPId );
    
    TInt count = iActiveProcessors.Count();
    while(count--)
        {
        MMTPRequestProcessor* processor = iActiveProcessors[count];
        TUint32 sessionId = processor->SessionId();
        if((sessionId == aSession.iMTPId) && (processor->Connection().ConnectionId() == aSession.iConnection.ConnectionId()))
            {
            iActiveProcessors.Remove(count);
            if (count == iActiveProcessor)
                {
                iActiveProcessorRemoved = ETrue;
                }
            else
                {
                processor->Release();
                }
            }
        }
    
    /**
     * We clear property manager cache when receiving session close notification from framework every times
     */
    iPropertyMgr->ClearAllCache();

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_SESSIONCLOSEDL_EXIT );
    }

/**
 Notify the data provider that the session opened
 
 @param aSessionId    The session Id opened
 @param aConnection   The connection of the sesssion
*/
#ifdef OST_TRACE_COMPILER_IN_USE
void CMTPImageDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& aSession)
#else
void CMTPImageDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/)
#endif
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_SESSIONOPENEDL_ENTRY );
    OstTrace1( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_SESSIONOPENEDL, "SessionID = %d", aSession.iMTPId );
    
    if (iEnumerated)
        {
        /**
         * Get image object count from framework and calculate the new pictures
         */
        TUint newPictures = QueryImageObjectCountL();        
        iNewPicNotifier->SetNewPictures(newPictures);
        OstTrace1( TRACE_NORMAL, DUP1_CMTPIMAGEDATAPROVIDER_SESSIONOPENEDL, 
                "CMTPImageDpEnumerator::CompleteEnumeration - New Pics: %d", newPictures );
        iEnumerated = EFalse;
        }

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_SESSIONOPENEDL_EXIT );
    }

/**
 Notify the data provider that the folder name has been changed
 
 @param aParam   The Rename notification
*/
void CMTPImageDataProvider::RenameObjectL(const TMTPNotificationParamsHandle& aParam)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_RENAMEOBJECTL_ENTRY );
    OstTraceExt2( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_RENAMEOBJECTL, 
            "Handle: %u, Old name: %S", aParam.iHandleId, aParam.iFileName);
    
    if (!iRenameObject)
        {
        iRenameObject = CMTPImageDpRenameObject::NewL(Framework(), *this);
        }

    iRenameObject->StartL(aParam.iHandleId, aParam.iFileName);    

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_RENAMEOBJECTL_EXIT );
    }

/**
 Find format code according to its extension name 
*/
TMTPFormatCode CMTPImageDataProvider::FindFormat(const TDesC& aExtension)
    {
    TMTPFormatCode* ret = iFormatMappings.Find(aExtension);
    if (ret == NULL)
        {
        return EMTPFormatCodeUndefined;
        }
    else
        {
        return *ret;
        }
    }

/**
 Find mime type according to its extension name 
*/
const TDesC& CMTPImageDataProvider::FindMimeType(const TDesC& aExtension)
    {
    /**
     * copy file extension by insensitive case
     */
    if (aExtension.Length() > KMaxExtNameLength)
        {
        return KNullDesC;
        }
    
    TBuf<KMaxExtNameLength> extension;
    extension.CopyLC(aExtension);
    
    const TDesC* ret = iMimeMappings.Find(extension);
    if (ret == NULL)
        {
        return KNullDesC;
        }
    else
        {
        return *ret;
        }
    }

/**
 Query image object count from current framework 
*/
TUint CMTPImageDataProvider::QueryImageObjectCountL()
    { 
    RMTPObjectMgrQueryContext   context;
    RArray<TUint>               handles;
    TMTPObjectMgrQueryParams    params(KMTPStorageAll, KMTPFormatsAll, KMTPHandleNone, Framework().DataProviderId());
    CleanupClosePushL(context);
    CleanupClosePushL(handles);    
    
    iNewPicHandles.Reset();
    
    do
        {
        /*
         * Speed up query performance, avoid to duplicated copy object handle between RArrays
         */
        Framework().ObjectMgr().GetObjectHandlesL(params, context, handles);
        }
    while (!context.QueryComplete());    
    
    CMTPObjectMetaData* objMetadata = CMTPObjectMetaData::NewLC();
    
    TUint newPictures = 0;
    TInt count = handles.Count();
    for (TInt i(0); i<count; ++i)
        {
        Framework().ObjectMgr().ObjectL(handles[i], *objMetadata);
        if (MTPImageDpUtilits::IsNewPicture(*objMetadata))
            {
            ++newPictures;
            iNewPicHandles.Append(handles[i]);
            }
        }
    
    
    CleanupStack::PopAndDestroy(objMetadata);
    CleanupStack::PopAndDestroy(&handles);
    CleanupStack::PopAndDestroy(&context);

    return newPictures;
    }

void CMTPImageDataProvider::AppendDeleteObjectsArrayL(const TDesC& aSuid)
    {
    iDeleteObjectsArray.AppendL(aSuid.AllocLC());
    CleanupStack::Pop();
    }

void CMTPImageDataProvider::HandleDeleteObjectsArray()
    {
    for ( TInt i = 0; i < iDeleteObjectsArray.Count(); i++ )
        {
        HBufC* object = iDeleteObjectsArray[i];
        TInt err = Framework().Fs().Delete(object->Des());
        OstTraceExt2( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_HANDLEDELETEOBJECTSARRAY, 
                "delete left objects %d error code is %d \n", i, err  );
        
        
        if ( err == KErrNone )
            {
            iDeleteObjectsArray.Remove(i);
            --i;
            delete object;
            object = NULL;
            }
        }
    }

void CMTPImageDataProvider::IncreaseNewPictures(TInt aCount)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_INCREASENEWPICTURES_ENTRY );
    OstTrace1( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_INCREASENEWPICTURES, "New Pictures: %d", aCount );

    iNewPicNotifier->IncreaseCount(aCount);    
 
    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_INCREASENEWPICTURES_EXIT );
    }

void CMTPImageDataProvider::DecreaseNewPictures(TInt aCount)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_DECREASENEWPICTURES_ENTRY );
    OstTrace1( TRACE_NORMAL, CMTPIMAGEDATAPROVIDER_DECREASENEWPICTURES, "New Pictures: %d", aCount );

    iNewPicNotifier->DecreaseCount(aCount);

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_DECREASENEWPICTURES_EXIT );
    }

void CMTPImageDataProvider::ResetNewPictures()
	{
	OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_RESETNEWPICTURES_ENTRY );

	iNewPicNotifier->SetNewPictures(0);
	
	TInt count = iNewPicHandles.Count();
	if (!count)
		{
		OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_RESETNEWPICTURES_EXIT );
		return;
		}

	CMTPObjectMetaData* objMetadata = CMTPObjectMetaData::NewLC();
	
	for (TInt i(0); i<count; ++i)
	{
		Framework().ObjectMgr().ObjectL(iNewPicHandles[i], *objMetadata);
		MTPImageDpUtilits::UpdateObjectStatusToOldL(Framework(), *objMetadata);
	}
	
	iNewPicHandles.Reset();
	CleanupStack::PopAndDestroy(objMetadata);

	OstTraceFunctionExit0( DUP1_CMTPIMAGEDATAPROVIDER_RESETNEWPICTURES_EXIT );
	}

void CMTPImageDataProvider::HandleMdeSessionCompleteL(TInt aError)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDATAPROVIDER_HANDLEMDESESSIONCOMPLETEL_ENTRY );

    NotifyEnumerationCompleteL(KMTPStorageAll, KErrNone);
    if (aError == KErrNone)
        {
        iMdeObserver = CMTPImageDpMdeObserver::NewL(Framework(), *this);
        iMdeObserver->SubscribeForChangeNotificationL();
        }

    OstTraceFunctionExit0( CMTPIMAGEDATAPROVIDER_HANDLEMDESESSIONCOMPLETEL_EXIT );
    }