mtpdataproviders/mtpimagedp/src/cmtpimagedpobjectpropertymgr.cpp
changeset 0 d0791faffa3f
child 2 4843bb5893b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpdataproviders/mtpimagedp/src/cmtpimagedpobjectpropertymgr.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,935 @@
+// 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 <bautils.h>
+#include <f32file.h>
+#include <bautils.h>
+#include <s32file.h>
+#include <e32const.h>
+#include <e32cmn.h>
+#include <imageconversion.h> 
+#include <mdeconstants.h>
+
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/cmtpobjectmetadata.h>
+#include <mtp/tmtptypeuint32.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/cmtptypearray.h>
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/mtpprotocolconstants.h>
+
+#include "cmtpimagedpobjectpropertymgr.h"
+#include "mtpimagedppanic.h"
+#include "mtpimagedputilits.h"
+#include "mtpimagedpconst.h"
+#include "mtpdebug.h"
+
+// Class constants.
+__FLOG_STMT(_LIT8(KComponent,"MTPImageDpPropertyMgr");)
+
+/**
+The properties cache table content.
+*/
+const CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::TElementMetaData CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::KElements[CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::ENumProperties] = 
+    {
+        {0, CMTPImagePropertiesCache::EUint}, // EImagePixWidth
+        {1, CMTPImagePropertiesCache::EUint}, // EImagePixHeight
+        {2, CMTPImagePropertiesCache::EUint}, // EImageBitDepth
+        {0, CMTPImagePropertiesCache::EDesC}, // EDateCreated
+    };
+
+CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache* CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::NewL()
+    {
+    CMTPImagePropertiesCache* self = new(ELeave) CMTPImagePropertiesCache(KElements, ENumProperties);
+    self->ConstructL();
+    return self;
+    }
+
+/**
+Destructor.
+*/
+CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::~CMTPImagePropertiesCache()
+    {
+    iElementsDesC.ResetAndDestroy();
+    iElementsUint.Reset();
+    } 
+
+/**
+Constructor.
+*/
+CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::CMTPImagePropertiesCache(const TElementMetaData* aElements, TUint aCount) :
+    iElements(sizeof(TElementMetaData), const_cast<TElementMetaData*>(aElements), aCount)
+    {
+    
+    }
+
+void CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::ConstructL()
+    {
+    const TUint KCount(iElements.Count());
+    for (TUint i(0); (i < KCount); i++)
+        {
+        const TElementMetaData& KElement(iElements[i]);
+        switch (KElement.iType)
+            {
+        case EDesC:
+            __ASSERT_DEBUG((iElementsDesC.Count() == KElement.iOffset), Panic(EMTPImageDpBadLayout));
+            iElementsDesC.AppendL(KNullDesC().AllocLC());
+            CleanupStack::Pop();
+            break;
+
+        case EUint:
+            __ASSERT_DEBUG((iElementsUint.Count() == KElement.iOffset), Panic(EMTPImageDpBadLayout));
+            iElementsUint.AppendL(0);
+            break;
+
+        default:
+            //nothing to do
+            __DEBUG_ONLY(User::Invariant());
+            break;
+            }         
+        }
+    
+    iObjectHandle = KMTPHandleNone;   
+    }
+
+void CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::ResetL()
+    {
+    SetUint(EImagePixWidth, 0);
+    SetUint(EImagePixHeight, 0);
+    SetUint(EImageBitDepth, 0);
+    SetDesCL(EDateCreated, KNullDesC);
+    }
+
+const TDesC& CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::DesC(TUint aId) const
+    {
+    __ASSERT_DEBUG((iElements[aId].iType == EDesC), Panic(EMTPImageDpTypeMismatch));
+    return *iElementsDesC[iElements[aId].iOffset];
+    }  
+
+TUint CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::Uint(TUint aId) const
+    {
+    __ASSERT_DEBUG((iElements[aId].iType == EUint), Panic(EMTPImageDpTypeMismatch));
+    return iElementsUint[iElements[aId].iOffset];
+    }
+
+TUint CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::ObjectHandle() const
+    {
+    return iObjectHandle;
+    }
+
+void CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::SetDesCL(TUint aId, const TDesC& aValue)
+    {
+    const TElementMetaData& KElement(iElements[aId]);
+    __ASSERT_DEBUG((KElement.iType == EDesC), Panic(EMTPImageDpTypeMismatch));
+    delete iElementsDesC[KElement.iOffset];
+    iElementsDesC[KElement.iOffset] = NULL;
+    iElementsDesC[KElement.iOffset] = aValue.AllocL();  
+    }
+
+void CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::SetUint(TUint aId, TUint aValue)
+    {
+    __ASSERT_DEBUG((iElements[aId].iType == EUint), Panic(EMTPImageDpTypeMismatch));
+    iElementsUint[iElements[aId].iOffset] = aValue;
+    }
+
+void CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::SetObjectHandle(TUint aObjectHandle)
+    {
+    iObjectHandle = aObjectHandle;
+    }
+
+CMTPImageDpObjectPropertyMgr* CMTPImageDpObjectPropertyMgr::NewL(MMTPDataProviderFramework& aFramework)
+    {
+    CMTPImageDpObjectPropertyMgr* self = new (ELeave) CMTPImageDpObjectPropertyMgr(aFramework);
+    CleanupStack::PushL(self);
+    self->ConstructL(aFramework);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CMTPImageDpObjectPropertyMgr::CMTPImageDpObjectPropertyMgr(MMTPDataProviderFramework& aFramework) :
+    iFs(aFramework.Fs()),
+    iObjectMgr(aFramework.ObjectMgr())
+    {
+    __FLOG_OPEN(KMTPSubsystem, KComponent);
+    }
+
+void CMTPImageDpObjectPropertyMgr::ConstructL(MMTPDataProviderFramework& /*aFramework*/)
+    {
+    __FLOG(_L8("CMTPImageDpObjectPropertyMgr::ConstructL - Entry"));
+    iPropertiesCache = CMTPImagePropertiesCache::NewL();    
+    iMetaDataSession = CMdESession::NewL(*this);
+    __FLOG(_L8("CMTPImageDpObjectPropertyMgr::ConstructL - Open Mde session"));
+    
+    iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
+    iActiveSchedulerWait->Start(); // wait for mdesession to start
+    if (iMdeSessionError != KErrNone) 
+        {
+        User::Leave(iMdeSessionError);
+        }
+    __FLOG(_L8("CMTPImageDpObjectPropertyMgr::ConstructL - Exit"));
+    }
+    
+CMTPImageDpObjectPropertyMgr::~CMTPImageDpObjectPropertyMgr()
+    {
+    __FLOG(_L8("CMTPImageDpObjectPropertyMgr::~CMTPImageDpObjectPropertyMgr - Entry"));
+    delete iPropertiesCache;
+    delete iObject;
+    delete iMetaDataSession;
+    delete iActiveSchedulerWait; 
+    __FLOG(_L8("CMTPImageDpObjectPropertyMgr::~CMTPImageDpObjectPropertyMgr - Exit"));
+    __FLOG_CLOSE;
+    }
+
+void CMTPImageDpObjectPropertyMgr::SetCurrentObjectL(CMTPObjectMetaData& aObjectInfo, TBool aRequireForModify, TBool aSaveToCache)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::SetCurrentObjectL"));
+    iObjectInfo = &aObjectInfo;
+
+    /**
+     * Image DP property manager will not directly modify properties which stored in the MdS
+     */
+    if(!aRequireForModify)
+        {
+        /**
+         * determine whether the cache hit is occured
+         */
+        if (iPropertiesCache->ObjectHandle() == iObjectInfo->Uint(CMTPObjectMetaData::EHandle))
+            {
+            iCacheHit = ETrue;
+            }
+        else
+            {
+            iCacheHit = EFalse;
+            
+            CMdENamespaceDef& defaultNamespace = iMetaDataSession->GetDefaultNamespaceDefL();
+            CMdEObjectDef& imageObjDef = defaultNamespace.GetObjectDefL( MdeConstants::Image::KImageObject );
+            delete iObject;
+            iObject = NULL;
+            
+            //if we can not open MdS object for getting properties, we will not get properites which stored in MdS
+            TFileName uri;
+            uri.CopyLC(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
+            TRAP_IGNORE((iObject = iMetaDataSession->GetObjectL(uri, imageObjDef)));            
+            }        
+        }    
+    else
+        {        
+        /**
+         * Set image object properties, because the cached properties are all readonly,
+         * so only sendobjectproplist/sendobjectinfo operations can use cache mechanism, 
+         * other operations will not use cache, such as setobjectvalue/setobjectproplist
+         */
+        if (aSaveToCache)
+            {
+            TUint objectHandle = iObjectInfo->Uint(CMTPObjectMetaData::EHandle);
+            if (iPropertiesCache->ObjectHandle() != objectHandle)
+                {
+                iPropertiesCache->ResetL();
+                }
+            iPropertiesCache->SetObjectHandle(objectHandle);            
+            }
+        }
+    
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::SetCurrentObjectL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::SetPropertyL(TMTPObjectPropertyCode aProperty, const TUint8 aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    if (aProperty == EMTPObjectPropCodeNonConsumable) 
+        {
+        iObjectInfo->SetUint(CMTPObjectMetaData::ENonConsumable, aValue);
+        }
+    else
+        {
+        User::Leave(EMTPRespCodeObjectPropNotSupported);
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::SetPropertyL(TMTPObjectPropertyCode aProperty, const TUint16 aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    switch(aProperty)
+        {
+    case EMTPObjectPropCodeObjectFormat:
+        iObjectInfo->SetUint(CMTPObjectMetaData::EFormatCode, aValue);
+        break;        
+    case EMTPObjectPropCodeProtectionStatus://this property does not supported by image dp
+        //nothing to do
+        break;
+    default:
+        //nothing to do
+        break;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::SetPropertyL(TMTPObjectPropertyCode aProperty, const TUint32 aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    switch(aProperty)
+        {
+    case EMTPObjectPropCodeStorageID:
+        iObjectInfo->SetUint(CMTPObjectMetaData::EStorageId, aValue);
+        break;
+    case EMTPObjectPropCodeParentObject:
+        iObjectInfo->SetUint(CMTPObjectMetaData::EParentHandle, aValue);
+        break;
+    case EMTPObjectPropCodeWidth:
+        iPropertiesCache->SetUint(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EImagePixWidth, aValue);
+        break;
+    case EMTPObjectPropCodeHeight:
+        iPropertiesCache->SetUint(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EImagePixHeight, aValue);
+        break; 
+    case EMTPObjectPropCodeImageBitDepth:
+        iPropertiesCache->SetUint(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EImageBitDepth, aValue);
+        break;          
+    default:
+        //nothing to do
+        break;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::SetPropertyL(TMTPObjectPropertyCode aProperty, const TDesC& aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    switch(aProperty)
+        {
+    case EMTPObjectPropCodeObjectFileName:
+        {
+        TParsePtrC oldUri = TParsePtrC(iObjectInfo->DesC(CMTPObjectMetaData::ESuid));
+        
+        //calculate new file name length
+        TInt len = oldUri.DriveAndPath().Length() + aValue.Length();
+        
+        //allocate memory for the new uri
+        RBuf  newUri;
+        newUri.CleanupClosePushL();
+        newUri.CreateL(len);
+        
+        //create the new uri
+        newUri.Append(oldUri.DriveAndPath());
+        newUri.Append(aValue);
+        newUri.Trim();
+        
+        //ask fs to rename file, leave if err returned from fs
+        User::LeaveIfError(iFs.Rename(oldUri.FullName(), newUri));
+        iObjectInfo->SetDesCL(CMTPObjectMetaData::ESuid, newUri);
+        CleanupStack::PopAndDestroy(&newUri);        
+        }
+        break;
+        
+    case EMTPObjectPropCodeName:
+        iObjectInfo->SetDesCL(CMTPObjectMetaData::EName, aValue);
+        break;
+              
+    case EMTPObjectPropCodeDateModified:
+        {
+        TTime modifiedTime;
+        ConvertMTPTimeStr2TTimeL(aValue, modifiedTime);
+        iFs.SetModified(iObjectInfo->DesC(CMTPObjectMetaData::ESuid), modifiedTime);     
+        }
+        break;
+      
+    case EMTPObjectPropCodeDateCreated://MdS property
+        iPropertiesCache->SetDesCL(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EDateCreated, aValue);
+        break;
+        
+    default:
+        //nothing to do
+        break;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::SetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::GetPropertyL(TMTPObjectPropertyCode aProperty, TUint8 &aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    if (aProperty == EMTPObjectPropCodeNonConsumable) 
+        {
+        aValue = iObjectInfo->Uint(CMTPObjectMetaData::ENonConsumable);       
+        }
+    else
+        {
+        User::Leave(EMTPRespCodeObjectPropNotSupported);
+        }     
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::GetPropertyL(TMTPObjectPropertyCode aProperty, TUint16 &aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    TEntry entry;
+    switch(aProperty)
+        {
+    case EMTPObjectPropCodeObjectFormat:
+        aValue = iObjectInfo->Uint(CMTPObjectMetaData::EFormatCode);
+        break;
+    case EMTPObjectPropCodeRepresentativeSampleFormat:
+        aValue = KThumbFormatCode;
+       break;        
+    case EMTPObjectPropCodeProtectionStatus:
+        iFs.Entry(iObjectInfo->DesC(CMTPObjectMetaData::ESuid), entry);
+        if (entry.IsReadOnly())
+            {
+            aValue = EMTPProtectionReadOnly;
+            }
+        else
+            {
+            aValue = EMTPProtectionNoProtection;
+            }
+        break;        
+    default:
+        GetPropertyFromMdsL(aProperty, &aValue);
+        break;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::GetPropertyL(TMTPObjectPropertyCode aProperty, TUint32 &aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    switch(aProperty)
+        {
+    case EMTPObjectPropCodeStorageID:
+        aValue = iObjectInfo->Uint(CMTPObjectMetaData::EStorageId);
+        break;
+        
+    case EMTPObjectPropCodeParentObject:
+        aValue = iObjectInfo->Uint(CMTPObjectMetaData::EParentHandle);
+        break;        
+       
+    case EMTPObjectPropCodeRepresentativeSampleSize:
+        aValue = KThumbCompressedSize;
+       break;       
+       
+    case EMTPObjectPropCodeRepresentativeSampleHeight:
+        aValue = KThumbHeigth;
+       break;
+       
+    case EMTPObjectPropCodeRepresentativeSampleWidth:
+        aValue = KThumbWidht;
+       break;
+              
+    default:
+        GetPropertyFromMdsL(aProperty, &aValue);
+        break;  
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    }
+    
+void CMTPImageDpObjectPropertyMgr::GetPropertyL(TMTPObjectPropertyCode aProperty, TUint64& aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+
+    if (aProperty == EMTPObjectPropCodeObjectSize) 
+        {
+        TEntry entry;
+        iFs.Entry(iObjectInfo->DesC(CMTPObjectMetaData::ESuid), entry);
+        aValue = entry.FileSize();            
+        }
+    else
+        {
+        User::Leave(EMTPRespCodeObjectPropNotSupported);
+        }    
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::GetPropertyL(TMTPObjectPropertyCode aProperty, TMTPTypeUint128& aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+    
+    if (aProperty == EMTPObjectPropCodePersistentUniqueObjectIdentifier) 
+        {
+        TUint32 handle = iObjectInfo->Uint(CMTPObjectMetaData::EHandle);
+        aValue = iObjectMgr.PuidL(handle);
+        }
+    else
+        {
+        User::Leave(EMTPRespCodeObjectPropNotSupported);
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    }
+    
+void CMTPImageDpObjectPropertyMgr::GetPropertyL(TMTPObjectPropertyCode aProperty, CMTPTypeString& aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    __ASSERT_DEBUG(iObjectInfo, Panic(EMTPImageDpObjectNull));
+
+    switch(aProperty)
+        {    
+    case EMTPObjectPropCodeObjectFileName:
+        {
+        TFileName name;
+        User::LeaveIfError(BaflUtils::MostSignificantPartOfFullName(iObjectInfo->DesC(CMTPObjectMetaData::ESuid), name));     
+        aValue.SetL(name);
+        }
+        break;
+        
+    case EMTPObjectPropCodeName:
+        {
+        aValue.SetL(iObjectInfo->DesC(CMTPObjectMetaData::EName));
+        }
+        break;
+        
+    case EMTPObjectPropCodeDateModified:
+        {
+        TBuf<64> dateString;
+        TEntry entry;
+        iFs.Entry(iObjectInfo->DesC(CMTPObjectMetaData::ESuid), entry);
+        
+        _LIT(KTimeFormat, "%F%Y%M%DT%H%T%S"); 
+        entry.iModified.FormatL(dateString, KTimeFormat);        
+        aValue.SetL(dateString);
+        }
+        break;                 
+        
+    default:
+        GetPropertyFromMdsL(aProperty, &aValue);
+        break;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyL"));
+    }
+
+void CMTPImageDpObjectPropertyMgr::GetPropertyFromMdsL(TMTPObjectPropertyCode aProperty, TAny* aValue)
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetPropertyFromMdsL"));
+    
+    TInt err = KErrNone;
+    CMdENamespaceDef& defaultNamespace = iMetaDataSession->GetDefaultNamespaceDefL();
+    CMdEObjectDef& imageObjDef = defaultNamespace.GetObjectDefL( MdeConstants::Image::KImageObject );
+    CMdEProperty* mdeProperty = NULL;
+    switch (aProperty)
+        {        
+    case EMTPObjectPropCodeDateCreated:
+        {
+        if (iCacheHit)
+            {
+            (*(static_cast<CMTPTypeString*>(aValue))).SetL(iPropertiesCache->DesC(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EDateCreated));
+            }
+        else if (iObject)
+            {        
+            CMdEPropertyDef& creationDatePropDef = imageObjDef.GetPropertyDefL(MdeConstants::Object::KCreationDateProperty);
+            TInt err = iObject->Property( creationDatePropDef, mdeProperty );  
+            if (err >= KErrNone) 
+                {
+                TBuf<KMaxTimeFormatSpec*2> timeValue;
+                // locale independent YYYYMMSSThhmmss, as required by the MTP spec
+                _LIT(KTimeFormat, "%F%Y%M%DT%H%T%S");
+                mdeProperty->TimeValueL().FormatL(timeValue, KTimeFormat);
+                (*(static_cast<CMTPTypeString*>(aValue))).SetL(timeValue);
+                }
+            }
+        }
+       break;  
+       
+    case EMTPObjectPropCodeWidth:
+        {
+        if (iCacheHit)
+            {
+            *static_cast<TUint32*>(aValue) = iPropertiesCache->Uint(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EImagePixWidth);
+            }
+        else if (iObject)
+            {
+            CMdEPropertyDef& imageWidthPropDef = imageObjDef.GetPropertyDefL(MdeConstants::MediaObject::KWidthProperty);
+            err = iObject->Property( imageWidthPropDef, mdeProperty );  
+            if (err >= KErrNone) 
+                {
+                TUint16 width = mdeProperty->Uint16ValueL();
+                if (width > 0)
+                    {
+                    *static_cast<TUint32*>(aValue) = width;
+                    }
+                else
+                    {
+                    *static_cast<TUint32*>(aValue) = ParseImageFileL(iObject->Uri(), EMTPObjectPropCodeWidth);
+                    }
+                }
+            else
+                {
+                *static_cast<TUint32*>(aValue) = ParseImageFileL(iObject->Uri(), EMTPObjectPropCodeWidth);
+                }
+            }
+        else
+            {
+            *static_cast<TUint32*>(aValue) = 0;
+            }
+        }
+       break; 
+       
+    case EMTPObjectPropCodeHeight:
+        {
+        if (iCacheHit)
+            {
+            *static_cast<TUint32*>(aValue) = iPropertiesCache->Uint(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EImagePixHeight);
+            }
+        else if (iObject)
+            {
+            CMdEPropertyDef& imageHeightPropDef = imageObjDef.GetPropertyDefL(MdeConstants::MediaObject::KHeightProperty);
+            err = iObject->Property( imageHeightPropDef, mdeProperty );  
+            if (err >= KErrNone) 
+                {
+                TUint16 height = mdeProperty->Uint16ValueL();
+                if (height > 0)
+                    {
+                    *static_cast<TUint32*>(aValue) = height;
+                    }
+                else
+                    {
+                    *static_cast<TUint32*>(aValue) = ParseImageFileL(iObject->Uri(), EMTPObjectPropCodeHeight);
+                    }
+                }
+            else
+                {
+                *static_cast<TUint32*>(aValue) = ParseImageFileL(iObject->Uri(), EMTPObjectPropCodeHeight);
+                }
+            }
+        else
+            {
+            *static_cast<TUint32*>(aValue) = 0;
+            }
+        }
+       break; 
+       
+    case EMTPObjectPropCodeImageBitDepth:
+        {
+        if (iCacheHit)
+            {
+            *static_cast<TUint32*>(aValue) = iPropertiesCache->Uint(CMTPImageDpObjectPropertyMgr::CMTPImagePropertiesCache::EImageBitDepth);
+            }
+        else if (iObject)
+            {
+            CMdEPropertyDef& imageBitDepth = imageObjDef.GetPropertyDefL(MdeConstants::Image::KBitsPerSampleProperty);
+            err = iObject->Property( imageBitDepth, mdeProperty );  
+            if (err >= KErrNone) 
+                {
+                TUint16 bitDepth = mdeProperty->Uint16ValueL();
+                if (bitDepth > 0)
+                    {
+                    *static_cast<TUint32*>(aValue) = bitDepth;
+                    }
+                else
+                    {
+                    *static_cast<TUint32*>(aValue) = ParseImageFileL(iObject->Uri(), EMTPObjectPropCodeImageBitDepth);
+                    }                
+                }
+            else
+                {
+                *static_cast<TUint32*>(aValue) = ParseImageFileL(iObject->Uri(), EMTPObjectPropCodeImageBitDepth);
+                }  
+            }
+        else
+            {
+            *static_cast<TUint32*>(aValue) = 0;
+            }        
+        }     
+       break; 
+       
+    default:
+        //nothing to do
+        break;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetPropertyFromMdsL"));
+    }
+
+TBool CMTPImageDpObjectPropertyMgr::GetYear(const TDesC& aDateString, TInt& aYear) const
+    {
+  __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetYear"));
+    aYear = 0;
+    TLex dateBuf(aDateString.Left(4));
+  __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetYear"));
+    return dateBuf.Val(aYear) == KErrNone;
+    }
+
+TBool CMTPImageDpObjectPropertyMgr::GetMonth(const TDesC& aDateString, TMonth& aMonth) const
+    {
+      __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetMonth"));
+    TBool result = EFalse;
+    aMonth = EJanuary;
+    TInt month = 0;
+    TLex dateBuf(aDateString.Mid(4, 2));
+    if(dateBuf.Val(month) == KErrNone && month > 0 && month < 13)
+        {
+        month--;
+        aMonth = (TMonth)month;
+        result = ETrue;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetMonth"));
+    return result;
+    }
+
+TBool CMTPImageDpObjectPropertyMgr::GetDay(const TDesC& aDateString, TInt& aDay) const
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetDay"));
+    TBool result = EFalse;
+    aDay = 0;
+    TLex dateBuf(aDateString.Mid(6, 2));
+    if(dateBuf.Val(aDay) == KErrNone && aDay > 0 && aDay < 32)
+        {
+        aDay--;
+        result = ETrue;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetDay"));
+    return result;	
+    }
+
+TBool CMTPImageDpObjectPropertyMgr::GetHour(const TDesC& aDateString, TInt& aHour) const
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetHour"));
+    aHour = 0;
+    TLex dateBuf(aDateString.Mid(9, 2));
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetHour"));
+    return (dateBuf.Val(aHour) == KErrNone && aHour >=0 && aHour < 60);
+    }
+                
+TBool CMTPImageDpObjectPropertyMgr::GetMinute(const TDesC& aDateString, TInt& aMinute) const
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetMinute"));
+    aMinute = 0;
+    TLex dateBuf(aDateString.Mid(11, 2));
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetMinute"));
+    return (dateBuf.Val(aMinute) == KErrNone && aMinute >=0 && aMinute < 60);
+    }
+
+TBool CMTPImageDpObjectPropertyMgr::GetSecond(const TDesC& aDateString, TInt& aSecond) const
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetSecond"));
+    aSecond = 0;
+    TLex dateBuf(aDateString.Mid(13, 2));
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetSecond"));
+    return (dateBuf.Val(aSecond) == KErrNone && aSecond >= 0 && aSecond < 60);
+    }
+
+TBool CMTPImageDpObjectPropertyMgr::GetTenthSecond(const TDesC& aDateString, TInt& aTenthSecond) const
+    {
+    __FLOG(_L8(">> CMTPImageDpObjectPropertyMgr::GetTenthSecond"));
+    TBool result = EFalse;
+    aTenthSecond = 0;
+    TInt dotPos = aDateString.Find(_L("."));
+    if(dotPos != KErrNotFound && dotPos < aDateString.Length() - 1)
+        {
+        TLex dateBuf(aDateString.Mid(dotPos + 1, 1));
+        result = (dateBuf.Val(aTenthSecond) == KErrNone && aTenthSecond >=0 && aTenthSecond < 10);
+        }
+    else
+        {
+        result = ETrue;
+        }
+    __FLOG(_L8("<< CMTPImageDpObjectPropertyMgr::GetTenthSecond"));
+    return result;	
+    }
+
+/*
+ * Convert the MTP datatime string to TTime:
+ * 
+ *  MTP datatime string format: YYYYMMDDThhmmss.s  Optional(.s)
+ *  TTime string format       : YYYYMMDD:HHMMSS.MMMMMM
+ *  
+ */
+void CMTPImageDpObjectPropertyMgr::ConvertMTPTimeStr2TTimeL(const TDesC& aTimeString, TTime& aModifiedTime) const
+    {
+    //Convert the Time String to TDateTime
+    TInt year = 0;
+    TMonth month;
+    TInt day = 0;
+    TInt hour = 0;
+    TInt minute = 0;
+    TInt second = 0;
+    TInt tenthSecond = 0;
+    
+    if(!GetYear(aTimeString,year)
+           ||!GetMonth(aTimeString,month)
+           ||!GetDay(aTimeString,day)
+           ||!GetHour(aTimeString,hour)
+           ||!GetMinute(aTimeString,minute)
+           ||!GetSecond(aTimeString,second)
+           ||!GetTenthSecond(aTimeString,tenthSecond))
+        {
+        User::Leave(KErrArgument);
+        }
+    else
+        {     
+        TDateTime dateTime(year, month, day, hour, minute, second, tenthSecond);
+        aModifiedTime = dateTime;
+        } 
+    }
+
+void CMTPImageDpObjectPropertyMgr::RemoveProperty(CMdEObject& aObject, CMdEPropertyDef& aPropDef)
+    {
+    __FLOG(_L8("CMTPImageDpObjectPropertyMgr::RemoveProperty"));
+    TInt index;
+    CMdEProperty* property;
+    index = aObject.Property(aPropDef, property);
+    if (index != KErrNotFound)
+        {
+        aObject.RemoveProperty(index);
+        }
+    }
+
+TUint32 CMTPImageDpObjectPropertyMgr::ParseImageFileL(const TDesC& aUri, TMTPObjectPropertyCode aPropCode)
+    {
+    TUint32 result = 0;
+    TInt err = KErrNone;
+    const TInt K64Kb = 65536;
+    
+    HBufC8* buffer = HBufC8::NewLC(K64Kb);
+    TPtr8 myImagePtr = buffer->Des();
+    err = iFs.ReadFileSection(aUri, 0, myImagePtr, K64Kb);
+    if (err != KErrNone)
+        {
+        CleanupStack::PopAndDestroy(buffer);
+        return result;
+        }
+    
+    CBufferedImageDecoder *decoder = CBufferedImageDecoder::NewL(iFs);
+    CleanupStack::PushL(decoder);
+        
+    decoder->OpenL(myImagePtr, CImageDecoder::TOptions( CImageDecoder::EPreferFastDecode | CImageDecoder::EOptionIgnoreExifMetaData));
+    if (decoder->ValidDecoder())
+        {
+        const TFrameInfo& info = decoder->FrameInfo();
+        
+        switch (aPropCode)
+            {
+        case EMTPObjectPropCodeWidth:
+            result = info.iOverallSizeInPixels.iWidth;
+            break;
+            
+        case EMTPObjectPropCodeHeight:
+            result = info.iOverallSizeInPixels.iHeight;
+            break;
+            
+        case EMTPObjectPropCodeImageBitDepth:
+            result = info.iBitsPerPixel;
+            break;
+            
+        default:
+            // nothing to do
+            break;
+            }
+        
+        /**
+         * Open MdE object for update image object properties after parsing
+         */
+        CMdENamespaceDef& defaultNamespace = iMetaDataSession->GetDefaultNamespaceDefL();
+        CMdEObjectDef& imageObjDef = defaultNamespace.GetObjectDefL(MdeConstants::Image::KImageObject);
+        CMdEPropertyDef& imageWidthPropDef = imageObjDef.GetPropertyDefL(MdeConstants::MediaObject::KWidthProperty);
+        CMdEPropertyDef& imageHeightPropDef = imageObjDef.GetPropertyDefL(MdeConstants::MediaObject::KHeightProperty);
+        CMdEPropertyDef& imageBitDepth = imageObjDef.GetPropertyDefL(MdeConstants::Image::KBitsPerSampleProperty);
+        
+        //update current object properties
+        TUint16 width = info.iOverallSizeInPixels.iWidth;
+        RemoveProperty(*iObject, imageWidthPropDef);
+        iObject->AddUint16PropertyL(imageWidthPropDef, width);
+        
+        TUint16 height = info.iOverallSizeInPixels.iHeight;
+        RemoveProperty(*iObject, imageHeightPropDef);
+        iObject->AddUint16PropertyL(imageHeightPropDef, height);
+        
+        TUint16 bitsPerPixel = info.iBitsPerPixel;
+        RemoveProperty(*iObject, imageBitDepth);
+        iObject->AddUint16PropertyL(imageBitDepth, bitsPerPixel);
+        
+        CMdEObject* updateObject = NULL;
+        TRAP(err, updateObject = iMetaDataSession->OpenObjectL(iObject->Id(), imageObjDef));
+        if (err == KErrNone && updateObject != NULL)
+            {
+            CleanupStack::PushL(updateObject);
+            
+            RemoveProperty(*updateObject, imageWidthPropDef);                   
+            updateObject->AddUint16PropertyL(imageWidthPropDef, width);    
+            
+            RemoveProperty(*updateObject, imageHeightPropDef);        
+            updateObject->AddUint16PropertyL(imageHeightPropDef, height);
+            
+            RemoveProperty(*updateObject, imageBitDepth);        
+            updateObject->AddUint16PropertyL(imageBitDepth, bitsPerPixel);    
+                    
+            iMetaDataSession->CommitObjectL(*updateObject);
+            CleanupStack::PopAndDestroy(updateObject);
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(2);// decoder, buffer
+    
+    return result;
+    }
+
+/**
+ * Return the mdesession instance
+ */
+CMdESession& CMTPImageDpObjectPropertyMgr::MdeSession()
+    {
+    return *iMetaDataSession;
+    }
+
+/**
+ *  From MMdESessionObserver
+ */
+void CMTPImageDpObjectPropertyMgr::HandleSessionOpened(CMdESession& /*aSession*/, TInt aError)
+    {   
+    SetMdeSessionError(aError);
+    if (iActiveSchedulerWait && iActiveSchedulerWait->IsStarted())
+        {
+        iActiveSchedulerWait->AsyncStop();  
+        }
+    }
+
+/**
+ *  From MMdESessionObserver
+ */
+void CMTPImageDpObjectPropertyMgr::HandleSessionError(CMdESession& /*aSession*/, TInt aError)
+    {
+    SetMdeSessionError(aError);
+    if (iActiveSchedulerWait && iActiveSchedulerWait->IsStarted())
+        {
+        iActiveSchedulerWait->AsyncStop();  
+        }  
+    }
+
+void CMTPImageDpObjectPropertyMgr::SetMdeSessionError(TInt aError)
+    {
+    iMdeSessionError = aError;
+    }
+
+void CMTPImageDpObjectPropertyMgr::ClearCacheL()
+    {
+    iPropertiesCache->ResetL();
+    }