14 * Description: Implement the operation: SendObjectInfo/SendObjectPropList/SendObject |
14 * Description: Implement the operation: SendObjectInfo/SendObjectPropList/SendObject |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <mtp/mmtpdataproviderframework.h> |
|
20 #include <mtp/mmtpobjectmgr.h> |
19 #include <mtp/mmtpobjectmgr.h> |
21 #include <mtp/cmtptypestring.h> |
20 #include <mtp/cmtptypestring.h> |
22 #include <mtp/cmtptypearray.h> |
|
23 #include <mtp/cmtptypeobjectinfo.h> |
21 #include <mtp/cmtptypeobjectinfo.h> |
24 #include <mtp/cmtptypefile.h> |
22 #include <mtp/cmtptypefile.h> |
25 #include <mtp/mmtpstoragemgr.h> |
23 #include <mtp/mmtpstoragemgr.h> |
26 #include <mtp/cmtpobjectmetadata.h> |
|
27 #include <bautils.h> |
24 #include <bautils.h> |
28 #include <mtp/cmtptypeobjectproplist.h> |
25 #include <mtp/cmtptypeobjectproplist.h> |
29 |
26 |
30 #include "csendobject.h" |
27 #include "csendobject.h" |
31 #include "mmmtpdpconfig.h" |
28 #include "mmmtpdpconfig.h" |
32 #include "mmmtpdputility.h" |
29 #include "mmmtpdputility.h" |
33 #include "tmmmtpdppanic.h" |
30 #include "tmmmtpdppanic.h" |
34 #include "mmmtpdplogger.h" |
31 #include "mmmtpdplogger.h" |
|
32 #include "cpropertysettingutility.h" |
35 #include "cmmmtpdpmetadataaccesswrapper.h" |
33 #include "cmmmtpdpmetadataaccesswrapper.h" |
36 |
34 |
37 // Verification data for the SendObjectInfo request |
35 // Verification data for the SendObjectInfo request |
38 const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] = |
36 const TMTPRequestElementInfo KMTPSendObjectInfoPolicy[] = |
39 { |
37 { |
55 KMTPHandleNone |
53 KMTPHandleNone |
56 } |
54 } |
57 }; |
55 }; |
58 |
56 |
59 // ----------------------------------------------------------------------------- |
57 // ----------------------------------------------------------------------------- |
|
58 // CSendObject::NewL |
|
59 // Two-phase construction method |
|
60 // ----------------------------------------------------------------------------- |
|
61 // |
|
62 EXPORT_C MMmRequestProcessor* CSendObject::NewL( MMTPDataProviderFramework& aFramework, |
|
63 MMTPConnection& aConnection, |
|
64 MMmMtpDpConfig& aDpConfig ) |
|
65 { |
|
66 CSendObject* self = new ( ELeave ) CSendObject( aFramework, aConnection, aDpConfig ); |
|
67 |
|
68 CleanupStack::PushL(self); |
|
69 self->ConstructL(); |
|
70 CleanupStack::Pop(self); |
|
71 |
|
72 return self; |
|
73 } |
|
74 |
|
75 // ----------------------------------------------------------------------------- |
60 // CSendObject::~CSendObject |
76 // CSendObject::~CSendObject |
61 // Destructor |
77 // Destructor |
62 // ----------------------------------------------------------------------------- |
78 // ----------------------------------------------------------------------------- |
63 // |
79 // |
64 EXPORT_C CSendObject::~CSendObject() |
80 EXPORT_C CSendObject::~CSendObject() |
65 { |
81 { |
66 if ( ( iProgress == EObjectInfoSucceed |
82 if ( !iNoRollback ) |
67 || iProgress == EObjectInfoFail |
|
68 || iProgress == EObjectInfoInProgress ) |
|
69 && !iNoRollback ) |
|
70 { |
83 { |
71 // Not finished SendObjectInfo \ SendObject pair detected. |
84 // Not finished SendObjectInfo \ SendObject pair detected. |
72 Rollback(); |
85 Rollback(); |
73 PRINT( _L( "MM MTP <> CSendObject::~CSendObject, Rollback" ) ); |
86 PRINT( _L( "MM MTP <> CSendObject::~CSendObject, Rollback" ) ); |
74 } |
87 } |
86 // ----------------------------------------------------------------------------- |
99 // ----------------------------------------------------------------------------- |
87 // CSendObject::CSendObject |
100 // CSendObject::CSendObject |
88 // Standard C++ Constructor |
101 // Standard C++ Constructor |
89 // ----------------------------------------------------------------------------- |
102 // ----------------------------------------------------------------------------- |
90 // |
103 // |
91 EXPORT_C CSendObject::CSendObject( MMTPDataProviderFramework& aFramework, |
104 CSendObject::CSendObject( MMTPDataProviderFramework& aFramework, |
92 MMTPConnection& aConnection, |
105 MMTPConnection& aConnection, |
93 MMmMtpDpConfig& aDpConfig ) : |
106 MMmMtpDpConfig& aDpConfig ) : |
94 CRequestProcessor( aFramework, aConnection, 0, NULL), |
107 CRequestProcessor( aFramework, aConnection, 0, NULL ), |
95 iFs( iFramework.Fs() ), |
108 iFs( iFramework.Fs() ), |
96 iObjectMgr( iFramework.ObjectMgr() ), |
109 iObjectMgr( iFramework.ObjectMgr() ), |
97 iDpConfig( aDpConfig ) |
110 iDpConfig( aDpConfig ) |
98 { |
111 { |
99 PRINT( _L( "Operation: SendObjectInfo/SendObject/SendObjectPropList(0x100C/0x100D/0x9808)" ) ); |
112 PRINT( _L( "Operation: SendObjectInfo/SendObject/SendObjectPropList(0x100C/0x100D/0x9808)" ) ); |
102 // ----------------------------------------------------------------------------- |
115 // ----------------------------------------------------------------------------- |
103 // CSendObject::ConstructL |
116 // CSendObject::ConstructL |
104 // 2nd Phase Constructor |
117 // 2nd Phase Constructor |
105 // ----------------------------------------------------------------------------- |
118 // ----------------------------------------------------------------------------- |
106 // |
119 // |
107 EXPORT_C void CSendObject::ConstructL() |
120 void CSendObject::ConstructL() |
108 { |
121 { |
109 PRINT( _L( "MM MTP => CSendObject::ConstructL" ) ); |
122 PRINT( _L( "MM MTP => CSendObject::ConstructL" ) ); |
110 |
123 |
111 iExpectedSendObjectRequest.SetUint16( TMTPTypeRequest::ERequestOperationCode, |
124 iExpectedSendObjectRequest.SetUint16( TMTPTypeRequest::ERequestOperationCode, |
112 EMTPOpCodeSendObject ); |
125 EMTPOpCodeSendObject ); |
561 { |
574 { |
562 PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseObjectL" ) ); |
575 PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseObjectL" ) ); |
563 |
576 |
564 TBool result = ETrue; |
577 TBool result = ETrue; |
565 |
578 |
566 delete iFileReceived; |
|
567 iFileReceived = NULL; |
|
568 |
|
569 TEntry fileEntry; |
|
570 User::LeaveIfError( iFs.Entry( iFullPath, fileEntry ) ); |
|
571 if ( fileEntry.iSize != iObjectSize ) |
|
572 { |
|
573 iFs.Delete( iFullPath ); |
|
574 iObjectMgr.UnreserveObjectHandleL( *iReceivedObjectInfo ); |
|
575 TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge; |
|
576 if ( fileEntry.iSize < iObjectSize ) |
|
577 { |
|
578 responseCode = EMTPRespCodeIncompleteTransfer; |
|
579 } |
|
580 SendResponseL( responseCode ); |
|
581 result = EFalse; |
|
582 } |
|
583 |
|
584 // SendObject is cancelled or connection is dropped. |
579 // SendObject is cancelled or connection is dropped. |
585 if ( result && iCancelled ) |
580 if ( iCancelled ) |
586 { |
581 { |
|
582 // In SendObject response phase, unregister is not necessary. |
|
583 // But there's no harm, still keep it here. |
587 iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest, |
584 iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest, |
588 iConnection ); |
585 iConnection ); |
|
586 |
589 Rollback(); |
587 Rollback(); |
590 SendResponseL( EMTPRespCodeTransactionCancelled ); |
588 SendResponseL( EMTPRespCodeTransactionCancelled ); |
591 } |
589 } |
592 else if ( result && !iCancelled ) |
590 else |
593 { |
591 { |
594 if ( iObjectSize > 0 ) // media file |
592 TEntry fileEntry; |
595 { |
593 User::LeaveIfError( iFs.Entry( iFullPath, fileEntry ) ); |
596 AddMediaToStoreL(); |
594 |
597 |
595 if ( fileEntry.FileSize() != iObjectSize ) |
598 if( iPreviousOperation == EMTPOpCodeSendObjectPropList ) |
596 { |
599 { |
597 Rollback(); |
600 SetObjectPropListL( *iObjectPropList ); |
598 TMTPResponseCode responseCode = EMTPRespCodeObjectTooLarge; |
601 } |
599 if ( fileEntry.FileSize() < iObjectSize ) |
602 |
600 { |
603 // Commits into MTP data object enumeration store the object handle and |
601 responseCode = EMTPRespCodeIncompleteTransfer; |
604 // storage space previously reserved for the specified object. |
602 } |
605 iFramework.ObjectMgr().CommitReservedObjectHandleL( *iReceivedObjectInfo ); |
603 SendResponseL( responseCode ); |
606 } |
604 result = EFalse; |
607 |
605 } |
608 // Commit object to MTP data store |
606 else |
609 iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest, |
607 { |
610 iConnection ); |
608 if ( iObjectSize > 0 ) // media file |
611 |
609 { |
612 SendResponseL( EMTPRespCodeOK ); |
610 TRAPD( err, AddMediaToStoreL() ); |
|
611 PRINT1( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseObjectL err = %d" ), err ); |
|
612 |
|
613 if ( ( iPreviousOperation == EMTPOpCodeSendObjectPropList ) |
|
614 && ( err == KErrNone ) ) |
|
615 { |
|
616 // Only leave when getting proplist element from data received by fw. |
|
617 // It should not happen after ReceiveDataL in which construction of proplist already succeed. |
|
618 SetObjectPropListL(); |
|
619 } |
|
620 |
|
621 // Commits into MTP data object enumeration store the object handle and |
|
622 // storage space previously reserved for the specified object. |
|
623 iFramework.ObjectMgr().CommitReservedObjectHandleL( *iReceivedObjectInfo ); |
|
624 } |
|
625 |
|
626 // In SendObject response phase, unregister is not necessary. |
|
627 // But there's no harm, still keep it here. |
|
628 iFramework.RouteRequestUnregisterL( iExpectedSendObjectRequest, |
|
629 iConnection ); |
|
630 |
|
631 SendResponseL( EMTPRespCodeOK ); |
|
632 } |
613 } |
633 } |
614 |
634 |
615 PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseObjectL result = %d" ), result ); |
635 PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseObjectL result = %d" ), result ); |
616 |
636 |
617 return result; |
637 return result; |
701 |
721 |
702 // Checking if the propCode is supported first then check its type |
722 // Checking if the propCode is supported first then check its type |
703 const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( iObjectFormat ); |
723 const RArray<TUint>* properties = iDpConfig.GetSupportedPropertiesL( iObjectFormat ); |
704 TUint16 propCode = aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ); |
724 TUint16 propCode = aElement.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ); |
705 TUint16 dataType = aElement.Uint16L( CMTPTypeObjectPropListElement::EDatatype ); |
725 TUint16 dataType = aElement.Uint16L( CMTPTypeObjectPropListElement::EDatatype ); |
706 PRINT2( _L( "MM MTP => CSendObject::CheckPropCodeL propCode = 0x%X, dataType = 0x%X" ), propCode, dataType ); |
726 PRINT2( _L( "MM MTP => CSendObject::CheckPropCodeL propCode = 0x%x, dataType = 0x%x" ), propCode, dataType ); |
707 |
727 |
708 responseCode = EMTPRespCodeInvalidObjectPropCode; |
728 responseCode = EMTPRespCodeInvalidObjectPropCode; |
709 const TInt count = properties->Count(); |
729 const TInt count = properties->Count(); |
710 for ( TInt i = 0; i < count; i++ ) |
730 for ( TInt i = 0; i < count; i++ ) |
711 { |
731 { |
803 break; |
822 break; |
804 |
823 |
805 default: |
824 default: |
806 // check types of DP specific properties |
825 // check types of DP specific properties |
807 // TODO: Is there anything except datatype need to be checked? |
826 // TODO: Is there anything except datatype need to be checked? |
808 responseCode = CheckSepecificPropType( propCode, dataType ); |
827 responseCode = MmMtpDpUtility::CheckPropType( propCode, dataType ); |
809 break; |
828 if ( responseCode == EMTPRespCodeAccessDenied ) |
810 } |
829 { |
811 |
830 responseCode = EMTPRespCodeOK; |
812 PRINT1( _L( "MM MTP <= CSendObject::CheckPropCode, responseCode = 0x%X" ), responseCode ); |
831 } |
|
832 break; |
|
833 } |
|
834 |
|
835 PRINT1( _L( "MM MTP <= CSendObject::CheckPropCode, responseCode = 0x%x" ), responseCode ); |
813 return responseCode; |
836 return responseCode; |
814 } |
837 } |
815 |
838 |
816 // ----------------------------------------------------------------------------- |
839 // ----------------------------------------------------------------------------- |
817 // Extracts the file information from the object property list element |
840 // Extracts the file information from the object property list element |
856 default: |
879 default: |
857 // Only extract necessary properties which conform to SendObjectInfo. |
880 // Only extract necessary properties which conform to SendObjectInfo. |
858 break; |
881 break; |
859 } |
882 } |
860 |
883 |
861 PRINT1( _L( "MM MTP <= CSendObject::ExtractPropertyL, responseCode = 0x%X" ), responseCode ); |
884 PRINT1( _L( "MM MTP <= CSendObject::ExtractPropertyL, responseCode = 0x%x" ), responseCode ); |
862 return responseCode; |
885 return responseCode; |
863 } |
886 } |
864 |
887 |
865 // ----------------------------------------------------------------------------- |
888 // ----------------------------------------------------------------------------- |
866 // CSendObject::SetObjectPropListL |
889 // CSendObject::SetObjectPropListL |
867 // Reserve object proplist into database |
890 // Reserve object proplist into database |
868 // ----------------------------------------------------------------------------- |
891 // ----------------------------------------------------------------------------- |
869 // |
892 // |
870 TMTPResponseCode CSendObject::SetObjectPropListL( const CMTPTypeObjectPropList& aPropList ) |
893 TMTPResponseCode CSendObject::SetObjectPropListL() |
871 { |
894 { |
872 PRINT( _L( "MM MTP => CSendObject::SetObjectPropListL" ) ); |
895 PRINT( _L( "MM MTP => CSendObject::SetObjectPropListL" ) ); |
873 |
896 |
874 TMTPResponseCode responseCode( EMTPRespCodeOK ); |
897 TMTPResponseCode responseCode( EMTPRespCodeOK ); |
875 |
898 |
880 const CMTPTypeObjectPropListElement& element( iObjectPropList->GetNextElementL() ); |
903 const CMTPTypeObjectPropListElement& element( iObjectPropList->GetNextElementL() ); |
881 |
904 |
882 TUint16 propertyCode = element.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ); |
905 TUint16 propertyCode = element.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode ); |
883 TUint16 dataType = element.Uint16L( CMTPTypeObjectPropListElement::EDatatype ); |
906 TUint16 dataType = element.Uint16L( CMTPTypeObjectPropListElement::EDatatype ); |
884 PRINT2( _L( "MM MTP <> SetObjectPropListL propertyCode = 0x%x, dataType = 0x%x" ), |
907 PRINT2( _L( "MM MTP <> SetObjectPropListL propertyCode = 0x%x, dataType = 0x%x" ), |
885 propertyCode, dataType ); |
908 propertyCode, |
|
909 dataType ); |
886 |
910 |
887 switch ( propertyCode ) |
911 switch ( propertyCode ) |
888 { |
912 { |
889 case EMTPObjectPropCodeStorageID: |
913 case EMTPObjectPropCodeStorageID: |
890 case EMTPObjectPropCodeObjectFormat: |
914 case EMTPObjectPropCodeObjectFormat: |
891 case EMTPObjectPropCodeProtectionStatus: |
|
892 case EMTPObjectPropCodeObjectSize: |
915 case EMTPObjectPropCodeObjectSize: |
893 case EMTPObjectPropCodeParentObject: |
916 case EMTPObjectPropCodeParentObject: |
894 case EMTPObjectPropCodePersistentUniqueObjectIdentifier: |
917 case EMTPObjectPropCodePersistentUniqueObjectIdentifier: |
895 // Do nothing for those properties are already set. |
918 // Do nothing for those properties are already set. |
896 break; |
919 break; |
897 |
920 |
898 case EMTPObjectPropCodeNonConsumable: |
921 case EMTPObjectPropCodeNonConsumable: |
|
922 iReceivedObjectInfo->SetUint( CMTPObjectMetaData::ENonConsumable, |
|
923 element.Uint8L( CMTPTypeObjectPropListElement::EValue ) ); |
|
924 break; |
|
925 |
899 case EMTPObjectPropCodeDateAdded: |
926 case EMTPObjectPropCodeDateAdded: |
900 case EMTPObjectPropCodeDateCreated: |
927 case EMTPObjectPropCodeDateCreated: |
901 case EMTPObjectPropCodeDateModified: |
928 case EMTPObjectPropCodeDateModified: |
902 case EMTPObjectPropCodeObjectFileName: |
929 case EMTPObjectPropCodeObjectFileName: |
903 // TODO: Does anything need to be done on these read-only properties? |
930 // Do nothing for read-only properties |
904 /* spec: |
931 /* spec: |
905 * Object properties that are get-only (0x00 GET) |
932 * Object properties that are get-only (0x00 GET) |
906 * should accept values during object creation by |
933 * should accept values during object creation by |
907 * way of the SendObjectPropList command. |
934 * way of the SendObjectPropList command. |
908 */ |
935 */ |
909 break; |
936 break; |
910 |
937 |
|
938 case EMTPObjectPropCodeProtectionStatus: |
|
939 // Already done in AddMediaToStore, it's not necessary to set it again. |
|
940 // SetProtectionStatus(); |
|
941 break; |
|
942 |
911 case EMTPObjectPropCodeName: |
943 case EMTPObjectPropCodeName: |
|
944 case EMTPObjectPropCodeAlbumArtist: |
912 { |
945 { |
913 CMTPTypeString* stringData = CMTPTypeString::NewLC( element.StringL( CMTPTypeObjectPropListElement::EValue ) );// + stringData |
946 CMTPTypeString* stringData = CMTPTypeString::NewLC( element.StringL( CMTPTypeObjectPropListElement::EValue ) );// + stringData |
914 |
947 |
915 responseCode = SetMetaDataToWrapperL( propertyCode, |
948 responseCode = iDpConfig.PropSettingUtility()->SetMetaDataToWrapper( iDpConfig, |
|
949 propertyCode, |
916 *stringData, |
950 *stringData, |
917 *iReceivedObjectInfo ); |
951 *iReceivedObjectInfo ); |
918 |
952 |
919 CleanupStack::PopAndDestroy( stringData );// - stringData |
953 CleanupStack::PopAndDestroy( stringData );// - stringData |
920 } |
954 } |
921 break; |
955 break; |
922 |
956 |
923 default: |
957 default: |
924 { |
958 { |
925 responseCode = SetSpecificObjectPropertyL( propertyCode, |
959 responseCode = iDpConfig.PropSettingUtility()->SetSpecificObjectPropertyL( iDpConfig, |
|
960 propertyCode, |
926 *iReceivedObjectInfo, |
961 *iReceivedObjectInfo, |
927 element ); |
962 element ); |
928 } |
963 } |
929 break; |
964 break; |
930 } // end of switch |
965 } // end of switch |
933 PRINT1( _L( "MM MTP <= CSendObject::SetObjectPropListL responseCode = 0x%x" ), responseCode ); |
968 PRINT1( _L( "MM MTP <= CSendObject::SetObjectPropListL responseCode = 0x%x" ), responseCode ); |
934 return responseCode; |
969 return responseCode; |
935 } |
970 } |
936 |
971 |
937 // ----------------------------------------------------------------------------- |
972 // ----------------------------------------------------------------------------- |
938 // CSendObject::SetMetaDataToWrapperL |
|
939 // |
|
940 // ----------------------------------------------------------------------------- |
|
941 // |
|
942 EXPORT_C TMTPResponseCode CSendObject::SetMetaDataToWrapperL( const TUint16 aPropCode, |
|
943 MMTPType& aNewData, |
|
944 const CMTPObjectMetaData& aObjectMetaData ) |
|
945 { |
|
946 TMTPResponseCode resCode = EMTPRespCodeOK; |
|
947 TRAPD( err, iDpConfig.GetWrapperL().SetObjectMetadataValueL( aPropCode, |
|
948 aNewData, |
|
949 aObjectMetaData ) ); |
|
950 |
|
951 PRINT1( _L("MM MTP <> CSendObject::SetMetaDataToWrapperL err = %d"), err); |
|
952 |
|
953 if ( err == KErrNone ) |
|
954 { |
|
955 resCode = EMTPRespCodeOK; |
|
956 } |
|
957 else if ( err == KErrTooBig ) |
|
958 // according to the codes of S60 |
|
959 { |
|
960 resCode = EMTPRespCodeInvalidDataset; |
|
961 } |
|
962 else if ( err == KErrPermissionDenied ) |
|
963 { |
|
964 resCode = EMTPRespCodeAccessDenied; |
|
965 } |
|
966 else if ( err == KErrNotFound ) |
|
967 { |
|
968 if ( MmMtpDpUtility::HasMetadata( aObjectMetaData.Uint( CMTPObjectMetaData::EFormatCode ) ) ) |
|
969 SendResponseL( EMTPRespCodeAccessDenied ); |
|
970 } |
|
971 else |
|
972 { |
|
973 err = HandleSpecificWrapperError( err, aObjectMetaData ); |
|
974 |
|
975 if ( err != KErrNone ) |
|
976 resCode = EMTPRespCodeGeneralError; |
|
977 } |
|
978 |
|
979 PRINT1( _L( "MM MTP <= CSendObject::SetMetaDataToWrapperL resCode = 0x%x" ), resCode ); |
|
980 |
|
981 return resCode; |
|
982 } |
|
983 |
|
984 // ----------------------------------------------------------------------------- |
|
985 // CSendObject::MatchStoreAndParentL |
973 // CSendObject::MatchStoreAndParentL |
986 // ----------------------------------------------------------------------------- |
974 // ----------------------------------------------------------------------------- |
987 // |
975 // |
988 TMTPResponseCode CSendObject::MatchStoreAndParentL() |
976 TMTPResponseCode CSendObject::MatchStoreAndParentL() |
989 { |
977 { |
990 TMTPResponseCode responseCode = EMTPRespCodeOK; |
978 TMTPResponseCode responseCode = EMTPRespCodeOK; |
991 |
979 |
992 iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter1 ); |
980 iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter1 ); |
993 iParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter2 ); |
981 iParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter2 ); |
994 PRINT2( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iStorageId = 0x%X, iParentHandle = 0x%X" ), |
982 PRINT2( _L( "MM MTP <> CSendObject::MatchStoreAndParentL, iStorageId = 0x%x, iParentHandle = 0x%x" ), |
995 iStorageId, |
983 iStorageId, |
996 iParentHandle ); |
984 iParentHandle ); |
997 |
985 |
998 if ( iStorageId == KMTPStorageDefault ) |
986 if ( iStorageId == KMTPStorageDefault ) |
999 { |
987 { |
1000 iStorageId = iDpConfig.GetDefaultStorageIdL(); |
988 iStorageId = iDpConfig.GetDefaultStorageIdL(); |
1001 PRINT1( _L( "MM MTP <> CSendObject::GetDefaultStorageIdL, iStorageId = 0x%X" ), iStorageId ); |
989 PRINT1( _L( "MM MTP <> CSendObject::GetDefaultStorageIdL, iStorageId = 0x%x" ), iStorageId ); |
1002 } |
990 } |
1003 |
991 |
1004 delete iParentSuid; |
992 delete iParentSuid; |
1005 iParentSuid = NULL; |
993 iParentSuid = NULL; |
1006 |
994 |
1044 // CSendObject::IsTooLarge |
1032 // CSendObject::IsTooLarge |
1045 // Check if the object is too large |
1033 // Check if the object is too large |
1046 // @return ETrue if yes, otherwise EFalse |
1034 // @return ETrue if yes, otherwise EFalse |
1047 // ----------------------------------------------------------------------------- |
1035 // ----------------------------------------------------------------------------- |
1048 // |
1036 // |
1049 TBool CSendObject::IsTooLarge( TUint32 aObjectSize ) const |
1037 TBool CSendObject::IsTooLarge( TUint64 aObjectSize ) const |
1050 { |
1038 { |
1051 TBool ret = ( aObjectSize > KMaxTInt ); |
1039 const TUint64 KMaxSupportedFileSize = 0xFFFFFFFF; //Maximal file size supported (4GB-1) |
1052 PRINT2( _L( "MM MTP <> CSendObject::IsTooLarge aObjectSize = %d, ret = %d" ), aObjectSize, ret ); |
1040 TBool ret = ( aObjectSize > KMaxSupportedFileSize ); |
|
1041 PRINT2( _L( "MM MTP <> CSendObject::IsTooLarge aObjectSize = 0x%Lx, ret = %d" ), aObjectSize, ret ); |
1053 return ret; |
1042 return ret; |
1054 } |
1043 } |
1055 |
1044 |
1056 // ----------------------------------------------------------------------------- |
1045 // ----------------------------------------------------------------------------- |
1057 // CSendObject::CanStoreFileL |
1046 // CSendObject::CanStoreFileL |
1089 TBool CSendObject::GetFullPathNameL( const TDesC& aFileName ) |
1078 TBool CSendObject::GetFullPathNameL( const TDesC& aFileName ) |
1090 { |
1079 { |
1091 PRINT1( _L("MM MTP => CSendObject::GetFullPathNameL aFileName = %S"), &aFileName ); |
1080 PRINT1( _L("MM MTP => CSendObject::GetFullPathNameL aFileName = %S"), &aFileName ); |
1092 |
1081 |
1093 TBool result( EFalse ); |
1082 TBool result( EFalse ); |
|
1083 |
1094 if ( aFileName.Length() > 0 ) |
1084 if ( aFileName.Length() > 0 ) |
1095 { |
1085 { |
1096 iFullPath.Zero(); |
1086 iFullPath.Zero(); |
1097 iFullPath.Append( *iParentSuid ); |
1087 iFullPath.Append( *iParentSuid ); |
1098 if ( ( iFullPath.Length() + aFileName.Length() ) < KMaxFileName ) |
1088 |
|
1089 // TODO: need to be done in derived class |
|
1090 // Only add extension for alb to pass winlogo test cases |
|
1091 TInt length = iFullPath.Length() + aFileName.Length(); |
|
1092 |
|
1093 TParsePtrC parser( aFileName ); |
|
1094 TBool isAlbWithoutExt = |
|
1095 ( ( iObjectFormat == EMTPFormatCodeAbstractAudioAlbum ) && ( !parser.ExtPresent() ) ); |
|
1096 if ( isAlbWithoutExt ) |
|
1097 length += KTxtExtensionALB().Length(); |
|
1098 |
|
1099 if ( length < KMaxFileName ) |
1099 { |
1100 { |
1100 iFullPath.Append( aFileName ); |
1101 iFullPath.Append( aFileName ); |
|
1102 if ( isAlbWithoutExt ) |
|
1103 iFullPath.Append( KTxtExtensionALB ); |
1101 PRINT1( _L( "MM MTP <> CSendObject::GetFullPathNameL iFullPath = %S" ), &iFullPath ); |
1104 PRINT1( _L( "MM MTP <> CSendObject::GetFullPathNameL iFullPath = %S" ), &iFullPath ); |
1102 result = iFramework.Fs().IsValidName( iFullPath ); |
1105 result = iFramework.Fs().IsValidName( iFullPath ); |
1103 } |
1106 } |
1104 } |
1107 } |
|
1108 |
1105 if ( result && ( iObjectFormat != MmMtpDpUtility::FormatFromFilename( iFullPath ) ) ) |
1109 if ( result && ( iObjectFormat != MmMtpDpUtility::FormatFromFilename( iFullPath ) ) ) |
1106 { |
1110 { |
1107 PRINT2( _L( "MM MTP <> %S does not match 0x%x" ), &iFullPath, iObjectFormat ); |
1111 PRINT2( _L( "MM MTP <> %S does not match 0x%x" ), &iFullPath, iObjectFormat ); |
1108 result = EFalse; |
1112 result = EFalse; |
1109 } |
1113 } |
1170 iObjectFormat ); |
1174 iObjectFormat ); |
1171 |
1175 |
1172 // Reserves space for and assigns an object handle to the object described |
1176 // Reserves space for and assigns an object handle to the object described |
1173 // by the specified object information record. |
1177 // by the specified object information record. |
1174 TRAP( err, iObjectMgr.ReserveObjectHandleL( *iReceivedObjectInfo, |
1178 TRAP( err, iObjectMgr.ReserveObjectHandleL( *iReceivedObjectInfo, |
1175 iObjectSize ) ); |
1179 iObjectSize ) ); |
1176 |
1180 |
1177 PRINT2( _L( "MM MTP => CSendObject::ReserveObjectL iObjectsize = %Lu, Operation: 0x%x" ), iObjectSize, iOperationCode ); |
1181 PRINT2( _L( "MM MTP => CSendObject::ReserveObjectL iObjectsize = %Lu, Operation: 0x%x" ), iObjectSize, iOperationCode ); |
1178 if ( err != KErrNone ) |
1182 if ( err != KErrNone ) |
1179 PRINT1( _L( "MM MTP <> CSendObject::ReserveObjectL err = %d" ), err ); |
1183 PRINT1( _L( "MM MTP <> CSendObject::ReserveObjectL err = %d" ), err ); |
1180 if ( iObjectSize == 0 ) |
1184 if ( iObjectSize == 0 ) |
1181 { |
1185 { |
|
1186 // Already trapped inside SaveEmptyFileL. |
1182 SaveEmptyFileL(); |
1187 SaveEmptyFileL(); |
|
1188 if( iOperationCode == EMTPOpCodeSendObjectPropList ) |
|
1189 { |
|
1190 // Only leave when getting proplist element from data received by fw. |
|
1191 // It should not happen after ReceiveDataL in which construction of proplist already succeed. |
|
1192 SetObjectPropListL(); |
|
1193 } |
|
1194 |
1183 iObjectMgr.CommitReservedObjectHandleL( *iReceivedObjectInfo ); |
1195 iObjectMgr.CommitReservedObjectHandleL( *iReceivedObjectInfo ); |
1184 } |
1196 } |
1185 |
1197 |
1186 iExpectedSendObjectRequest.SetUint32( TMTPTypeRequest::ERequestSessionID, |
1198 iExpectedSendObjectRequest.SetUint32( TMTPTypeRequest::ERequestSessionID, |
1187 iSessionId ); |
1199 iSessionId ); |
1195 |
1207 |
1196 PRINT( _L( "MM MTP <= CSendObject::ReserveObjectL" ) ); |
1208 PRINT( _L( "MM MTP <= CSendObject::ReserveObjectL" ) ); |
1197 } |
1209 } |
1198 |
1210 |
1199 // ----------------------------------------------------------------------------- |
1211 // ----------------------------------------------------------------------------- |
1200 // CSendObject::SetProtectionStatusL |
1212 // CSendObject::SetProtectionStatus |
1201 // ----------------------------------------------------------------------------- |
1213 // ----------------------------------------------------------------------------- |
1202 // |
1214 // |
1203 void CSendObject::SetProtectionStatusL() |
1215 void CSendObject::SetProtectionStatus() |
1204 { |
1216 { |
1205 PRINT1( _L( "MM MTP => CSendObject::SetProtectionStatusL iProtectionStatus = %d" ), iProtectionStatus ); |
1217 PRINT1( _L( "MM MTP => CSendObject::SetProtectionStatus iProtectionStatus = %d" ), iProtectionStatus ); |
1206 |
1218 |
1207 if ( iProtectionStatus == EMTPProtectionNoProtection |
1219 if ( iFileReceived != NULL ) |
1208 || iProtectionStatus == EMTPProtectionReadOnly ) |
1220 { |
1209 { |
1221 if ( iProtectionStatus == EMTPProtectionNoProtection |
1210 // TODO: wait for review |
1222 || iProtectionStatus == EMTPProtectionReadOnly ) |
1211 TInt err = KErrNone; |
1223 { |
1212 if ( iProtectionStatus == EMTPProtectionNoProtection ) |
1224 TInt err = KErrNone; |
1213 { |
1225 if ( iProtectionStatus == EMTPProtectionNoProtection ) |
1214 iFs.SetAtt( iFullPath, KEntryAttNormal, KEntryAttReadOnly ); |
1226 { |
1215 } |
1227 err = iFileReceived->File().SetAtt( KEntryAttNormal, KEntryAttReadOnly ); |
1216 else |
1228 } |
1217 { |
1229 else |
1218 iFs.SetAtt( iFullPath, KEntryAttReadOnly, KEntryAttNormal ); |
1230 { |
1219 } |
1231 err = iFileReceived->File().SetAtt( KEntryAttReadOnly, KEntryAttNormal ); |
1220 User::LeaveIfError( err ); |
1232 } |
1221 } |
1233 |
1222 PRINT( _L( "MM MTP <= CSendObject::SetProtectionStatusL" ) ); |
1234 if ( err != KErrNone ) |
|
1235 { |
|
1236 PRINT1( _L("MM MTP <> CSendObject::SetProtectionStatus err = %d" ), err ); |
|
1237 } |
|
1238 } |
|
1239 // Close the file after SetProtectionStatus to make sure other process won't open |
|
1240 // the file successfully right at the time calling RFile::SetAtt. |
|
1241 delete iFileReceived; |
|
1242 iFileReceived = NULL; |
|
1243 } |
|
1244 |
|
1245 PRINT( _L( "MM MTP <= CSendObject::SetProtectionStatus" ) ); |
1223 } |
1246 } |
1224 |
1247 |
1225 // ----------------------------------------------------------------------------- |
1248 // ----------------------------------------------------------------------------- |
1226 // CSendObject::SaveEmptyFileL |
1249 // CSendObject::SaveEmptyFileL |
1227 // ----------------------------------------------------------------------------- |
1250 // ----------------------------------------------------------------------------- |
1230 { |
1253 { |
1231 PRINT( _L( "MM MTP => CSendObject::SaveEmptyFileL" ) ); |
1254 PRINT( _L( "MM MTP => CSendObject::SaveEmptyFileL" ) ); |
1232 |
1255 |
1233 RFile file; |
1256 RFile file; |
1234 User::LeaveIfError( file.Create( iFs, iFullPath, EFileWrite ) ); |
1257 User::LeaveIfError( file.Create( iFs, iFullPath, EFileWrite ) ); |
1235 file.Close(); |
1258 CleanupClosePushL( file ); // + file |
1236 |
|
1237 // set entry protection status and modified date |
|
1238 SetProtectionStatusL(); |
|
1239 |
|
1240 // add playlist to MPX DB |
|
1241 TParsePtrC parse( iFullPath ); |
|
1242 iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() ); |
|
1243 iDpConfig.GetWrapperL().AddObjectL( iFullPath ); |
|
1244 |
1259 |
1245 if ( EMTPFormatCodeAbstractAudioVideoPlaylist == iObjectFormat ) |
1260 if ( EMTPFormatCodeAbstractAudioVideoPlaylist == iObjectFormat ) |
1246 { |
1261 { |
1247 TInt err = KErrNone; |
1262 TInt err = KErrNone; |
1248 err = iFs.SetAtt( iFullPath, |
1263 err = file.SetAtt( KEntryAttSystem | KEntryAttHidden, |
1249 KEntryAttSystem | KEntryAttHidden, |
|
1250 KEntryAttReadOnly | KEntryAttNormal ); |
1264 KEntryAttReadOnly | KEntryAttNormal ); |
1251 if ( err != KErrNone ) |
1265 if ( err != KErrNone ) |
1252 PRINT1( _L( "MM MTP <> CSendObject::SaveEmptyFileL err = %d" ), err ); |
1266 PRINT1( _L( "MM MTP <> CSendObject::SaveEmptyFileL err = %d" ), err ); |
1253 iDpConfig.GetWrapperL().AddDummyFileL( iFullPath ); |
1267 iDpConfig.GetWrapperL().AddDummyFileL( iFullPath ); |
1254 } |
1268 } |
1255 |
1269 CleanupStack::PopAndDestroy( &file ); // - file |
1256 PRINT( _L( "MM MTP <= CSendObject::SaveEmptyFileL" ) ); |
1270 |
|
1271 // add playlist to MPX DB |
|
1272 TRAPD( err, AddMediaToStoreL() ); |
|
1273 |
|
1274 if ( err != KErrNone ) |
|
1275 { |
|
1276 // Ignore err even add into MPX get failed. |
|
1277 } |
|
1278 |
|
1279 PRINT1( _L( "MM MTP <= CSendObject::SaveEmptyFileLerr = %d" ), err ); |
1257 } |
1280 } |
1258 |
1281 |
1259 // ----------------------------------------------------------------------------- |
1282 // ----------------------------------------------------------------------------- |
1260 // CSendObject::AddMediaToStoreL() |
1283 // CSendObject::AddMediaToStoreL() |
1261 // |
1284 // |
1263 // |
1286 // |
1264 void CSendObject::AddMediaToStoreL() |
1287 void CSendObject::AddMediaToStoreL() |
1265 { |
1288 { |
1266 PRINT( _L( "MM MTP => CSendObject::AddMediaToStoreL" ) ); |
1289 PRINT( _L( "MM MTP => CSendObject::AddMediaToStoreL" ) ); |
1267 |
1290 |
1268 TBool isVideo = EFalse; |
1291 // SetProtectionStatus here make sure no matter the previous operation is SendObjectInfo |
1269 switch ( iObjectFormat ) |
1292 // or SendObjectPropList |
1270 { |
1293 // Might need to set dateadded and datemodify for further extension. |
1271 case EMTPFormatCode3GPContainer: |
1294 SetProtectionStatus(); |
1272 case EMTPFormatCodeMP4Container: |
1295 |
1273 case EMTPFormatCodeASF: |
1296 iDpConfig.GetWrapperL().SetStorageRootL( iFullPath ); |
1274 { |
1297 PRINT1( _L( "MM MTP <> CSendObject::AddMediaToStoreL iFullPath = %S" ), &iFullPath ); |
1275 TMmMtpSubFormatCode subFormatCode; |
1298 iDpConfig.GetWrapperL().AddObjectL( *iReceivedObjectInfo ); |
1276 |
1299 |
1277 if ( MmMtpDpUtility::IsVideoL( iFullPath ) ) |
1300 iDpConfig.GetWrapperL().SetImageObjPropL( *iReceivedObjectInfo, iWidth, iHeight ); |
1278 { |
|
1279 subFormatCode = EMTPSubFormatCodeVideo; |
|
1280 isVideo = ETrue; |
|
1281 } |
|
1282 else |
|
1283 { |
|
1284 subFormatCode = EMTPSubFormatCodeAudio; |
|
1285 isVideo = EFalse; |
|
1286 } |
|
1287 |
|
1288 iReceivedObjectInfo->SetUint( CMTPObjectMetaData::EFormatSubCode, |
|
1289 ( TUint ) subFormatCode ); |
|
1290 } |
|
1291 break; |
|
1292 |
|
1293 // put all just video format codes here |
|
1294 case EMTPFormatCodeWMV: |
|
1295 { |
|
1296 isVideo = ETrue; |
|
1297 } |
|
1298 break; |
|
1299 |
|
1300 default: |
|
1301 PRINT( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseObjectL default" ) ); |
|
1302 break; |
|
1303 } |
|
1304 |
|
1305 TPtrC suid( iReceivedObjectInfo->DesC( CMTPObjectMetaData::ESuid ) ); |
|
1306 PRINT1( _L( "MM MTP <> CSendObject::AddMediaToStoreL suid = %S" ), &suid ); |
|
1307 TParsePtrC parse( suid ); |
|
1308 iDpConfig.GetWrapperL().SetStorageRootL( parse.Drive() ); |
|
1309 iDpConfig.GetWrapperL().AddObjectL( iFullPath, isVideo ); |
|
1310 |
|
1311 if ( isVideo ) |
|
1312 { |
|
1313 TInt err = KErrNone; |
|
1314 TRAP( err, iDpConfig.GetWrapperL().SetImageObjPropL( iFullPath, iWidth, iHeight ) ); |
|
1315 |
|
1316 PRINT1( _L( "MM MTP <= CSendObject::AddVideoToStoreL err = %d" ), err ); |
|
1317 } |
|
1318 |
1301 |
1319 PRINT( _L( "MM MTP <= CSendObject::AddMediaToStoreL" ) ); |
1302 PRINT( _L( "MM MTP <= CSendObject::AddMediaToStoreL" ) ); |
1320 } |
1303 } |
1321 |
1304 |
1322 // ----------------------------------------------------------------------------- |
1305 // ----------------------------------------------------------------------------- |
1337 // ----------------------------------------------------------------------------- |
1320 // ----------------------------------------------------------------------------- |
1338 // |
1321 // |
1339 void CSendObject::Rollback() |
1322 void CSendObject::Rollback() |
1340 { |
1323 { |
1341 // Delete this object from file system. |
1324 // Delete this object from file system. |
1342 if ( iProgress == ESendObjectInProgress ) |
1325 if ( iProgress == ESendObjectInProgress |
|
1326 || iProgress == EObjectInfoSucceed |
|
1327 ||iProgress == EObjectInfoFail ) |
1343 { |
1328 { |
1344 PRINT1( _L( "MM MTP <> CSendObject::Rollback ROLLBACK_FILE %S" ), &iFullPath ); |
1329 PRINT1( _L( "MM MTP <> CSendObject::Rollback ROLLBACK_FILE %S" ), &iFullPath ); |
|
1330 // Close the interrupted transfer file by delete iFileReceived object |
|
1331 delete iFileReceived; |
|
1332 iFileReceived = NULL; |
|
1333 |
1345 iFramework.Fs().Delete( iFullPath ); |
1334 iFramework.Fs().Delete( iFullPath ); |
1346 TRAP_IGNORE( iFramework.ObjectMgr().UnreserveObjectHandleL( *iReceivedObjectInfo ) ); |
1335 TRAP_IGNORE( iFramework.ObjectMgr().UnreserveObjectHandleL( *iReceivedObjectInfo ) ); |
1347 iProgress = EObjectNone; |
1336 iProgress = EObjectNone; |
1348 } |
1337 } |
1349 } |
1338 } |
1350 |
1339 |
1351 // end of file |
1340 // end of file |