--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cgetobjectproplist.cpp Thu Dec 17 08:55:47 2009 +0200
@@ -0,0 +1,863 @@
+/*
+* 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: GetObjectPropList
+*
+*/
+
+
+#include <bautils.h>
+#include <e32std.h>
+#include <mtp/mmtpdataproviderframework.h>
+#include <mtp/mmtpobjectmgr.h>
+#include <mtp/cmtptypeobjectproplist.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/cmtptypearray.h>
+#include <mtp/cmtpobjectmetadata.h>
+
+#include "tobjectdescription.h"
+#include "cgetobjectproplist.h"
+#include "tmmmtpdppanic.h"
+#include "mmmtpdplogger.h"
+#include "mmmtpdpconfig.h"
+#include "mmmtpdputility.h"
+#include "cmmmtpdpmetadataaccesswrapper.h"
+
+static const TUint32 KMTPAll = 0xffffffff;
+_LIT( KMtpDateTimeFormat, "%F%Y%M%DT%H%T%S" );
+const TInt KMtpMaxDateTimeStringLength = 15;
+
+#if defined(_DEBUG) || defined(MMMTPDP_PERFLOG)
+_LIT( KSubFormatParse, "SubFormatParse" );
+#endif
+
+// Verification data for the getObjectPropList request
+const TMTPRequestElementInfo KMTPGetObjectPropListPolicy[] =
+ {
+ {
+ TMTPTypeRequest::ERequestParameter1,
+ EMTPElementTypeObjectHandle,
+ EMTPElementAttrNone,
+ 2,
+ KMTPHandleAll,
+ KMTPHandleNone
+ }
+ };
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::~CGetObjectPropList
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGetObjectPropList::~CGetObjectPropList()
+ {
+ Cancel();
+
+ delete iObject;
+ delete iPropertyList;
+ delete iPropertyElement;
+ iHandles.Close();
+ iPropertyArray.Close();
+
+#if defined(_DEBUG) || defined(MMMTPDP_PERFLOG)
+ delete iPerfLog;
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::CGetObjectPropList
+// Standard C++ Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGetObjectPropList::CGetObjectPropList( MMTPDataProviderFramework& aFramework,
+ MMTPConnection& aConnection,
+ MMmMtpDpConfig& aDpConfig ) :
+ CRequestProcessor( aFramework,
+ aConnection,
+ sizeof ( KMTPGetObjectPropListPolicy ) / sizeof( TMTPRequestElementInfo ),
+ KMTPGetObjectPropListPolicy ),
+ iHandles ( KMmMtpRArrayGranularity ),
+ iDpConfig( aDpConfig ),
+ iPropertyArray( KMmMtpRArrayGranularity )
+ {
+ PRINT( _L( "Operation: GetObjectPropList(0x9805)" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::ConstructL
+// 2nd Phase Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGetObjectPropList::ConstructL()
+ {
+ CActiveScheduler::Add( this );
+
+ iPropertyList = CMTPTypeObjectPropList::NewL();
+
+ SetPSStatus();
+
+#if defined(_DEBUG) || defined(MMMTPDP_PERFLOG)
+ iPerfLog = CMmMtpDpPerfLog::NewL( _L( "MediaMtpDataProviderEnumerator" ) );
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::CheckRequestL
+// Verify the reqeust and returns it
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TMTPResponseCode CGetObjectPropList::CheckRequestL()
+ {
+ PRINT( _L( "MM MTP => CGetObjectPropList::CheckRequestL" ) );
+
+ TMTPResponseCode result = CRequestProcessor::CheckRequestL();
+
+ if ( result == EMTPRespCodeOK )
+ {
+ result = CheckFormatL();
+ }
+
+ if ( result == EMTPRespCodeOK )
+ {
+ result = CheckDepth();
+ }
+
+ if ( result == EMTPRespCodeOK )
+ {
+ result = CheckPropCodeL();
+ }
+
+ PRINT1( _L("MM MTP <= CGetObjectPropList::CheckRequestL, response 0x%x"), result );
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::ServiceL
+// service a request at request phase
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGetObjectPropList::ServiceL()
+ {
+ GetObjectHandlesL();
+ TInt numOfObjects = iHandles.Count();
+ PRINT2( _L( "MM MTP <> CGetObjectPropList::ServiceL, numOfObjects = %d, iPropCode = 0x%x" ),
+ numOfObjects,
+ iPropCode );
+ if ( numOfObjects > 0
+ && ( iPropCode == KMTPAll || iPropCode == EMTPObjectPropCodeUndefined ) )
+ {
+ // iFirstUnprocessed = 0;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, iStatus.Int() );
+ SetActive();
+ }
+ else
+ {
+ TInt err = KErrNone;
+ for ( TInt i = 0; i < numOfObjects; i++ )
+ {
+ TUint32 handle = iHandles[i ];
+
+ if ( iFramework.ObjectMgr().ObjectOwnerId( handle )
+ == iFramework.DataProviderId() )
+ {
+ delete iObject;
+ iObject = NULL;
+ iObject = CMTPObjectMetaData::NewL();
+
+ if ( iFramework.ObjectMgr().ObjectL( handle, *iObject ) ) // Populate the object meta data
+ {
+ SetSubFormatCodeL();
+
+ err = ServiceOneObjectPropertyL( handle, iPropCode );
+ if ( err != KErrNone && err != KErrNotSupported )
+ break;
+ }
+ }
+ }
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::ServiceL, one property was queried, Send data to PC! err = %d" ), err );
+ if ( err == KErrNone || err == KErrNotSupported )
+ SendDataL( *iPropertyList );
+ else if ( err == KErrNotFound )
+ SendResponseL( EMTPRespCodeAccessDenied );
+ else
+ SendResponseL( EMTPRespCodeGeneralError );
+ }
+
+ PRINT( _L( "MM MTP <= CGetObjectPropList::ServiceL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::CheckFormatL
+// Ensures the object format operation parameter is valid
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CGetObjectPropList::CheckFormatL() const
+ {
+ TMTPResponseCode response = EMTPRespCodeOK;
+
+ PRINT( _L( "MM MTP => CGetObjectPropList::CheckFormatL" ) );
+
+ TUint32 formatCode = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
+ iFormatCode = formatCode;
+
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::CheckFormatL formatCode = 0x%x" ), formatCode );
+
+ if ( formatCode != 0 )
+ {
+ response = EMTPRespCodeInvalidObjectFormatCode;
+
+ const RArray<TUint>* format = iDpConfig.GetSupportedFormat();
+ TInt count = format->Count();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( formatCode == (*format)[i ] )
+ {
+ response = EMTPRespCodeOK;
+ break;
+ }
+ }
+ }
+
+ PRINT1( _L( "MM MTP <= CGetObjectPropList::CheckFormatL, response 0x%x" ), response );
+
+ return response;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::CheckPropCodeL
+// Ensures the object prop code operation parameter is valid
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CGetObjectPropList::CheckPropCodeL() const
+ {
+ PRINT( _L( "MM MTP => CGetObjectPropList::CheckPropCode" ) );
+
+ TMTPResponseCode response = EMTPRespCodeOK;
+
+ TUint32 formatCode = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
+ iPropCode = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::CheckPropCode, iPropCode = 0x%x" ), iPropCode );
+
+ iPropertyArray.Reset();
+ if ( iPropCode == EMTPObjectPropCodeUndefined )
+ {
+ // Get group code
+ TUint32 groupCode = Request().Uint32( TMTPTypeRequest::ERequestParameter4 );
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::CheckPropCode, Group Code = 0x%x" ), groupCode );
+
+ // check if groupCode is supported
+ TInt count = sizeof ( KSupportedGroupCode )
+ / sizeof ( KSupportedGroupCode[0] );
+ TInt i = 0;
+ for ( ; i < count; i++ )
+ {
+ if ( groupCode == KSupportedGroupCode[i ] )
+ break;
+ }
+ if ( i == count )
+ response = EMTPRespCodeSpecificationByGroupUnsupported;
+
+ }
+ else if ( iPropCode != KMTPAll )
+ {
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::CheckPropCode, Property(0x%x) was queried." ), iPropCode );
+
+ TInt err = KErrNone;
+ const RArray<TUint>* properties = NULL;
+ if ( formatCode == KMTPFormatsAll )
+ properties = iDpConfig.GetAllSupportedProperties();
+ else
+ properties = iDpConfig.GetSupportedPropertiesL( formatCode );
+
+ User::LeaveIfError( err );
+
+ const TInt count = properties->Count();
+ TInt i = 0;
+ for ( i = 0; i < count; i++ )
+ {
+ if ( (*properties)[i] == iPropCode )
+ {
+ iPropertyArray.Append( iPropCode );
+ break;
+ }
+ }
+
+ if ( iPropertyArray.Count() == 0 )
+ {
+ response = EMTPRespCodeInvalidObjectPropCode;
+ }
+ }
+ else
+ {
+ PRINT( _L( "MM MTP <> CGetObjectPropList::CheckPropCode, All properties were queried." ) );
+ }
+
+ PRINT1( _L( "MM MTP <= CGetObjectPropList::CheckPropCode, response 0x%x" ), response );
+
+ return response;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::CheckDepth
+// Ensures the depth operation parameter is valid
+// -----------------------------------------------------------------------------
+//
+TMTPResponseCode CGetObjectPropList::CheckDepth() const
+ {
+ TMTPResponseCode response = EMTPRespCodeSpecificationByDepthUnsupported;
+
+ PRINT( _L( "MM MTP => CGetObjectPropList::CheckDepth" ) );
+
+ // We either support no depth at all, or 1 depth or (0xFFFFFFFF) with objecthandle as 0x00000000
+ iHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::CheckDepth iHandle = 0x%x" ), iHandle );
+ iDepth = Request().Uint32( TMTPTypeRequest::ERequestParameter5 );
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::CheckDepth iDepth = 0x%x" ), iDepth );
+
+ if ( ( iDepth == 0 )
+ || ( iDepth == 1 )
+ || ( iDepth == KMTPAll && iHandle == KMTPHandleNone ) )
+ {
+ response = EMTPRespCodeOK;
+ }
+
+ PRINT1( _L( "MM MTP <= CGetObjectPropList::CheckDepth, response 0x%x" ), response );
+
+ return response;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::GetObjectHandlesL
+// Gets the handles for the objects that we want the properties for
+// -----------------------------------------------------------------------------
+//
+void CGetObjectPropList::GetObjectHandlesL()
+ {
+ PRINT( _L( "MM MTP => CGetObjectPropList::GetObjectHandlesL" ) );
+
+ iHandles.Reset();
+
+ if ( iHandle == KMTPHandleAll )
+ {
+ GetObjectHandlesL( KMTPStorageAll, KMTPHandleNone );
+ }
+ else if ( iHandle == KMTPHandleNone )
+ {
+ GetRootObjectHandlesL( iDepth, iFormatCode );
+ }
+ else
+ {
+ CMTPObjectMetaData* meta( iRequestChecker->GetObjectInfo( iHandle ) );
+ TPtrC suid( meta->DesC( CMTPObjectMetaData::ESuid ) );
+ TParsePtrC parse( suid );
+ iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() );
+
+ __ASSERT_DEBUG( meta, Panic( EMmMTPDpObjectNull ) );
+
+ if ( ( meta->Uint( CMTPObjectMetaData::EFormatCode ) == EMTPFormatCodeAssociation )
+ && ( meta->Uint( CMTPObjectMetaData::EFormatSubCode ) == EMTPAssociationTypeGenericFolder ) )
+ {
+ GetFolderObjectHandlesL( iDepth, iHandle );
+ }
+ else
+ {
+ iHandles.Append( iHandle );
+ }
+ }
+
+ PRINT( _L( "MM MTP <= CGetObjectPropList::GetObjectHandlesL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::GetObjectHandlesL
+// Gets all object handles (for GetObjectHandlesL)
+// -----------------------------------------------------------------------------
+//
+void CGetObjectPropList::GetObjectHandlesL( TUint32 aStorageId,
+ TUint32 aParentHandle,
+ TUint16 aFormat /*= 0x0000*/)
+ {
+ PRINT2( _L( "MM MTP => CGetObjectPropList::GetObjectHandlesL, aStorageId = 0x%x, aParentHandle = 0x%x" ),
+ aStorageId,
+ aParentHandle );
+
+ RMTPObjectMgrQueryContext context;
+ CleanupClosePushL( context ); // + context
+
+ iHandles.Reset();
+
+ if ( aFormat )
+ {
+ TMTPObjectMgrQueryParams params( aStorageId, aFormat, aParentHandle );
+
+ do
+ {
+ iFramework.ObjectMgr().GetObjectHandlesL( params, context, iHandles );
+ }
+ while ( !context.QueryComplete() );
+ }
+ else
+ {
+ TMTPObjectMgrQueryParams params( aStorageId,
+ KMTPFormatsAll,
+ aParentHandle );
+
+ do
+ {
+ RArray<TUint> handles;
+ CleanupClosePushL( handles ); // + handles
+ iFramework.ObjectMgr().GetObjectHandlesL( params, context, handles );
+
+ for ( TInt i = 0; i < handles.Count(); i++ )
+ {
+ if ( iFramework.ObjectMgr().ObjectOwnerId( handles[i ] )
+ == iFramework.DataProviderId() )
+ iHandles.Append( handles[i ] );
+ }
+ CleanupStack::PopAndDestroy( &handles ); // - handles
+ }
+ while ( !context.QueryComplete() );
+ }
+
+ CleanupStack::PopAndDestroy( &context ); // - context
+
+ PRINT( _L( "MM MTP <= CGetObjectPropList::GetObjectHandlesL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::GetFolderObjectHandlesL
+// Gets a folder object handle
+// -----------------------------------------------------------------------------
+//
+void CGetObjectPropList::GetFolderObjectHandlesL( TUint32 aDepth,
+ TUint32 aParentHandle )
+ {
+ PRINT2( _L( "MM MTP => CGetObjectPropList::GetFolderObjectHandlesL aDepth = 0x%x, aParentHandle = 0x%x" ),
+ aDepth,
+ aParentHandle );
+
+ if ( aDepth == 0 )
+ {
+ // Do Nothing!!!
+ }
+ else //if(aDepth ==1)
+ {
+ GetObjectHandlesL( KMTPStorageAll, aParentHandle, iFormatCode );
+ }
+
+ PRINT( _L( "MM MTP <= CGetObjectPropList::GetFolderObjectHandlesL" ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::GetRootObjectHandlesL
+// Gets the handles of all objects on the root
+// -----------------------------------------------------------------------------
+//
+void CGetObjectPropList::GetRootObjectHandlesL( TUint32 aDepth, TUint16 aFormat )
+ {
+ PRINT2( _L( "MM MTP => CGetObjectPropList::GetRootObjectHandlesL aDepth = 0x%x, aFormat = 0x%x" ), aDepth , aFormat);
+
+ if ( aDepth == KMaxTUint )
+ {
+ GetObjectHandlesL( KMTPStorageAll, KMTPHandleNone, aFormat );
+ }
+ else if ( aDepth == 0 )
+ {
+ // Return empty set to PC according to spec 0.96, folder is handled by device dp
+ iHandles.Reset();
+ }
+ else
+ {
+ GetObjectHandlesL( KMTPStorageAll, KMTPHandleNoParent, aFormat );
+ }
+
+ PRINT( _L( "MM MTP <= CGetObjectPropList::GetRootObjectHandlesL" ) );
+ }
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::ServiceAllPropertiesL
+// Gets a list of all the properties supported
+// -----------------------------------------------------------------------------
+//
+TInt CGetObjectPropList::ServiceAllPropertiesL( TUint32 aHandle )
+ {
+ PRINT1( _L( "MM MTP => CGetObjectPropList::ServiceAllPropertiesL aHandle = 0x%x" ), aHandle );
+
+ // Append the current object info onto our list
+ TFileName fileName( iObject->DesC( CMTPObjectMetaData::ESuid ) );
+ TUint32 formatCode = iObject->Uint( CMTPObjectMetaData::EFormatCode );
+
+ PRINT2( _L( "MM MTP <> CGetObjectPropList::ServiceAllPropertiesL, fileName = %S, formatCode = 0x%x" ),
+ &fileName,
+ formatCode );
+
+ const RArray<TUint>* properties = NULL;
+ if ( formatCode == KMTPFormatsAll )
+ properties = iDpConfig.GetAllSupportedProperties();
+ else
+ properties = iDpConfig.GetSupportedPropertiesL( formatCode );
+
+ const TInt count = properties->Count();
+
+ TInt err = KErrNone;
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // no need to do the trap anymore, this is being handle internally in Media DP's ServiceSpecificObjectPropertyL, also, this base class should not know too much of different handling between different formats
+ err = ServiceOneObjectPropertyL( aHandle, (*properties)[i] );
+ if ( err == KErrNotSupported ) // Skip
+ err = KErrNone;
+ if ( err != KErrNone )
+ break;
+ }
+
+ PRINT1( _L( "MM MTP <= CGetObjectPropList::ServiceAllPropertiesL err = %d" ), err );
+ return err;
+ }
+
+TInt CGetObjectPropList::ServiceGroupPropertiesL( TUint32 aHandle )
+ {
+ PRINT1( _L( "MM MTP => CGetObjectPropList::ServiceGroupPropertiesL aHandle = 0x%x" ), aHandle );
+
+ TFileName fileName( iObject->DesC( CMTPObjectMetaData::ESuid ) );
+ TUint32 formatCode = iObject->Uint( CMTPObjectMetaData::EFormatCode );
+
+ PRINT2( _L( "MM MTP <> CGetObjectPropList::ServiceGroupPropertiesL, fileName = %S, formatCode = 0x%x" ),
+ &fileName,
+ formatCode );
+
+ // Get property codes according to group code, put those into array
+ TUint32 groupCode = Request().Uint32( TMTPTypeRequest::ERequestParameter4 );
+ iPropertyArray.Reset();
+ GetPropertiesL( iPropertyArray, groupCode, formatCode );
+
+ const TInt count = iPropertyArray.Count();
+
+ TInt err = KErrNone;
+ for ( TInt i = 0; i < count; i++ )
+ {
+ err = ServiceOneObjectPropertyL( aHandle, iPropertyArray[i] );
+ if ( err == KErrNotSupported ) // Skip
+ err = KErrNone;
+ if ( err != KErrNone )
+ break;
+ }
+
+ PRINT1( _L( "MM MTP <= CGetObjectPropList::ServiceGroupPropertiesL err = %d" ), err );
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::ServiceOneObjectPropertyL
+// Gets the object property information for the required object
+// -----------------------------------------------------------------------------
+//
+TInt CGetObjectPropList::ServiceOneObjectPropertyL( TUint32 aHandle,
+ TUint16 aPropCode )
+ {
+ PRINT2( _L( "MM MTP => CGetObjectPropList::ServiceOneObjectPropertyL aHandle = 0x%x, aPropCode = 0x%x" ),
+ aHandle,
+ aPropCode );
+ CMTPTypeString* textData = NULL;
+ TInt err = KErrNone;
+
+ if ( iPropertyElement != NULL )
+ {
+ delete iPropertyElement;
+ iPropertyElement = NULL;
+ }
+
+ switch ( aPropCode )
+ {
+ // Storage ID
+ case EMTPObjectPropCodeStorageID:
+ {
+ TMTPTypeUint32 storageId( iObject->Uint( CMTPObjectMetaData::EStorageId ) );
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetUint32L(CMTPTypeObjectPropListElement::EValue, storageId.Value());
+ }
+ break;
+
+ // Format Code
+ case EMTPObjectPropCodeObjectFormat:
+ {
+ TMTPTypeUint16 objectFormat( iObject->Uint( CMTPObjectMetaData::EFormatCode ) );
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetUint16L(CMTPTypeObjectPropListElement::EValue, objectFormat.Value());
+ }
+ break;
+
+ // Protection Status
+ case EMTPObjectPropCodeProtectionStatus:
+ {
+ TMTPTypeUint16 protectionStatus( MmMtpDpUtility::GetProtectionStatusL( iFramework.Fs(),
+ iObject->DesC( CMTPObjectMetaData::ESuid ) ) );
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetUint16L(CMTPTypeObjectPropListElement::EValue, protectionStatus.Value());
+ }
+ break;
+
+ // Object Size
+ case EMTPObjectPropCodeObjectSize:
+ {
+ TMTPTypeUint64 objectSize( MmMtpDpUtility::GetObjectSizeL( iFramework.Fs(),
+ iObject->DesC( CMTPObjectMetaData::ESuid ) ) );
+ iPropertyElement = &( iPropertyList->ReservePropElemL( aHandle, aPropCode ) );
+ iPropertyElement->SetUint64L( CMTPTypeObjectPropListElement::EValue, objectSize.Value() );
+ }
+ break;
+
+ // Filename
+ case EMTPObjectPropCodeObjectFileName:
+ {
+#ifdef _DEBUG
+ HBufC* log = iObject->DesC( CMTPObjectMetaData::ESuid ).Alloc();
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::ServiceOneObjectPropertyL FileName = %S" ), log );
+ delete log;
+ log = NULL;
+#endif // _DEBUG
+ TParsePtrC parse( iObject->DesC( CMTPObjectMetaData::ESuid ) );
+ textData = CMTPTypeString::NewLC( parse.NameAndExt() ); // + textData
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetStringL(CMTPTypeObjectPropListElement::EValue, textData->StringChars());
+ CleanupStack::PopAndDestroy( textData ); // - textData
+ }
+ break;
+
+ // Parent Object
+ case EMTPObjectPropCodeParentObject:
+ {
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetUint32L(CMTPTypeObjectPropListElement::EValue, iObject->Uint( CMTPObjectMetaData::EParentHandle ));
+ }
+ break;
+
+ // PUID
+ case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
+ {
+ TMTPTypeUint128 puid = iFramework.ObjectMgr().PuidL( aHandle );
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetUint128L(CMTPTypeObjectPropListElement::EValue,puid.UpperValue(), puid.LowerValue() );
+ }
+ break;
+
+ case EMTPObjectPropCodeName:
+ case EMTPObjectPropCodeDateAdded:
+ {
+ if ( ( aPropCode == EMTPObjectPropCodeName )
+ || ( ( !MmMtpDpUtility::IsVideoL( iObject->DesC( CMTPObjectMetaData::ESuid ), iFramework ) )
+ && ( aPropCode == EMTPObjectPropCodeDateAdded ) ) )
+ {
+ textData = CMTPTypeString::NewLC(); // + textData
+
+ TRAP( err, iDpConfig.GetWrapperL().GetObjectMetadataValueL( aPropCode,
+ *textData,
+ *iObject ) );
+
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::ServiceOneObjectPropertyL err = %d" ), err );
+
+ if ( err == KErrNone )
+ {
+ iPropertyElement = &(iPropertyList->ReservePropElemL( aHandle, aPropCode ) );
+ iPropertyElement->SetStringL(CMTPTypeObjectPropListElement::EValue, textData->StringChars());
+ }
+
+ CleanupStack::PopAndDestroy( textData ); // - textData
+ }
+ }
+ break;
+
+ case EMTPObjectPropCodeDateCreated:
+ case EMTPObjectPropCodeDateModified:
+ {
+ TTime dataModified;
+ dataModified = MmMtpDpUtility::GetObjectDateModifiedL( iFramework.Fs(),
+ iObject->DesC( CMTPObjectMetaData::ESuid ) );
+
+ TBuf<KMtpMaxDateTimeStringLength> timeStr;
+ dataModified.FormatL( timeStr, KMtpDateTimeFormat );
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::ServiceOneObjectPropertyL Date time %S" ), &timeStr );
+ CMTPTypeString* datastring = CMTPTypeString::NewLC( timeStr ); // + datastring
+
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetStringL(CMTPTypeObjectPropListElement::EValue, datastring->StringChars());
+ CleanupStack::PopAndDestroy( datastring ); // - datastring
+ }
+ break;
+
+ // Consumable Value
+ case EMTPObjectPropCodeNonConsumable:
+ {
+ iPropertyElement = &(iPropertyList->ReservePropElemL(aHandle, aPropCode));
+ iPropertyElement->SetUint8L(CMTPTypeObjectPropListElement::EValue,0);
+ }
+ break;
+
+ default:
+ {
+ err = ServiceSpecificObjectPropertyL( aPropCode, aHandle );
+ }
+ break;
+ }
+
+ if ( iPropertyElement != NULL )
+ {
+ iPropertyList->CommitPropElemL( *iPropertyElement );
+ iPropertyElement = NULL;
+ }
+
+ PRINT( _L( "MM MTP <= CGetObjectPropList::ServiceOneObjectPropertyL" ) );
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::RunL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGetObjectPropList::RunL()
+ {
+ if ( iHandles.Count() > 0 )
+ {
+ TInt err = KErrNone;
+ TUint32 handle = iHandles[0];
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::RunL, handle = 0x%x" ), handle );
+ if ( iFramework.ObjectMgr().ObjectOwnerId( handle )
+ == iFramework.DataProviderId() )
+ {
+ delete iObject;
+ iObject = NULL;
+ iObject = CMTPObjectMetaData::NewL();
+
+ if ( iFramework.ObjectMgr().ObjectL( handle, *iObject ) ) // Populate the object meta data
+ {
+ SetSubFormatCodeL();
+
+ if ( iPropCode == KMTPAll )
+ err = ServiceAllPropertiesL( handle );
+ else if ( iPropCode == EMTPObjectPropCodeUndefined )
+ {
+ err = ServiceGroupPropertiesL( handle );
+ }
+ if ( err == KErrNotFound )
+ SendResponseL( EMTPRespCodeAccessDenied );
+ else if ( err != KErrNone )
+ SendResponseL( EMTPRespCodeGeneralError );
+ }
+ }
+
+ // Complete ourselves with current TRequestStatus
+ // Increase index to process next handle on next round
+ // iFirstUnprocessed++;
+ iHandles.Remove( 0 );
+
+ if ( err == KErrNone )
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, iStatus.Int() );
+ SetActive();
+ }
+ }
+ else // all handles processed, can send data
+ {
+ PRINT( _L( "MM MTP <> CGetObjectPropList::RunL, Finished, Send data to PC!" ) );
+ SendDataL( *iPropertyList );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::RunError
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CGetObjectPropList::RunError( TInt aError )
+ {
+ PRINT1( _L( "MM MTP <> CGetObjectPropList::RunError aError = %d" ), aError );
+ TRAP_IGNORE( SendResponseL( EMTPRespCodeGeneralError ) );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CGetObjectPropList::DoCancel()
+// Cancel the process
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGetObjectPropList::DoCancel()
+ {
+ // TODO: need to send the data here?
+ // SendDataL( *iPropertyList );
+ }
+
+void CGetObjectPropList::GetPropertiesL( RArray<TUint>& aPropArray,
+ TUint32 aGroupCode,
+ TUint16 aFormatCode ) const
+ {
+ aPropArray.Reset();
+
+ const RArray<TUint>* properties = NULL;
+ if ( aFormatCode == KMTPFormatsAll )
+ properties = iDpConfig.GetAllSupportedProperties();
+ else
+ properties = iDpConfig.GetSupportedPropertiesL( aFormatCode );
+
+ TInt count = sizeof ( KPropGroupMapTable ) / sizeof ( KPropGroupMapTable[0] );
+ for ( TInt i = 0; i < properties->Count(); i++ )
+ {
+ for ( TInt j = 0; j < count; j++ )
+ {
+ if( KPropGroupMapTable[j].iPropCode == (*properties)[i]
+ && KPropGroupMapTable[j].iGroupCode == aGroupCode )
+ {
+ aPropArray.Append( (*properties)[i] );
+ break;
+ }
+ }
+ }
+ }
+
+void CGetObjectPropList::SetSubFormatCodeL()
+ {
+ __ASSERT_DEBUG( iObject, Panic( EMmMTPDpObjectNull ) );
+
+ // Note: Parsing out subformat code in external enumeration phase.
+ // This process was delayed in internal phase to avoid time-out.
+ TUint16 formatCode = iObject->Uint( CMTPObjectMetaData::EFormatCode );
+ TUint subFormatCode = iObject->Uint( CMTPObjectMetaData::EFormatSubCode );
+ PRINT2( _L( "MM MTP <> CGetObjectPropList::SetSubFormatCode, formatCode = 0x%x, subFormatCode = 0x%x" ),
+ formatCode,
+ subFormatCode );
+
+ TBool ifNeedParse = ( ( formatCode == EMTPFormatCodeMP4Container )
+ || ( formatCode == EMTPFormatCode3GPContainer )
+ || ( formatCode== EMTPFormatCodeASF ) )
+ && ( subFormatCode == EMTPSubFormatCodeUnknown );
+ if ( ifNeedParse )
+ {
+ PERFLOGSTART( KSubFormatParse );
+
+ if ( MmMtpDpUtility::IsVideoL( iObject->DesC( CMTPObjectMetaData::ESuid ) ) )
+ subFormatCode = EMTPSubFormatCodeVideo;
+ else
+ subFormatCode = EMTPSubFormatCodeAudio;
+
+ PERFLOGSTOP( KSubFormatParse );
+
+ iObject->SetUint( CMTPObjectMetaData::EFormatSubCode, subFormatCode );
+ }
+ }
+
+// end of file