mmsengine/mmsmessage/src/mmsdrm.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *     Handles DRM attachments
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include    "mmsdrm.h"
       
    24 
       
    25 // drm 
       
    26 #include <e32base.h>
       
    27 #include <e32std.h>
       
    28 #include <f32file.h>
       
    29 
       
    30 #include    <apmstd.h>
       
    31 
       
    32 #include    <s32mem.h>
       
    33 #include    <cmsvattachment.h>
       
    34 #include    <cmsvmimeheaders.h>
       
    35 #include    <msvstore.h>
       
    36 #include    <DRMRights.h>
       
    37 #include    <DrmPermission.h>
       
    38 #include    <DrmConstraint.h>
       
    39 #include    <DRMTypes.h>
       
    40 
       
    41 // mms private headers
       
    42 #include    "mmsconst.h"
       
    43 #include    "mmserrors.h"
       
    44 
       
    45 // CONSTANTS
       
    46 
       
    47 const TInt KMms2 = 2; // just get rid of codescammer complaints
       
    48 const TInt KMmsAssetLength = 1024; // just an estimate
       
    49 
       
    50 // LOCAL FUNCTION PROTOTYPES
       
    51 
       
    52 
       
    53 // ================= MEMBER FUNCTIONS =======================
       
    54 
       
    55 
       
    56 // ---------------------------------------------------------
       
    57 //
       
    58 // ---------------------------------------------------------
       
    59 //
       
    60 CMmsDrmCaf::CMmsDrmCaf()
       
    61     {
       
    62     }
       
    63 
       
    64 // ---------------------------------------------------------
       
    65 //
       
    66 // ---------------------------------------------------------
       
    67 //
       
    68 CMmsDrmCaf* CMmsDrmCaf::NewL()
       
    69     {
       
    70     CMmsDrmCaf* self = new (ELeave) CMmsDrmCaf();
       
    71     
       
    72     CleanupStack::PushL( self );
       
    73     self->ConstructL();
       
    74     CleanupStack::Pop( self );
       
    75     
       
    76     return self;
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------
       
    80 //
       
    81 // ---------------------------------------------------------
       
    82 //
       
    83 void CMmsDrmCaf::ConstructL()
       
    84     {
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------
       
    88 //
       
    89 // ---------------------------------------------------------
       
    90 //
       
    91 CMmsDrmCaf::~CMmsDrmCaf()
       
    92     {
       
    93     delete iAttachmentFilePath;
       
    94 	delete iSupplier;
       
    95 	delete iImportFile;
       
    96     }
       
    97 
       
    98 // ---------------------------------------------------------
       
    99 //
       
   100 // ---------------------------------------------------------
       
   101 //
       
   102 TBool CMmsDrmCaf::RegisterL( const CMsvMimeHeaders& aMimeHeaders )
       
   103     {
       
   104     // We allocate the supplier only when needed
       
   105 	if( !iSupplier )
       
   106 		{		
       
   107 		iSupplier = CSupplier::NewL();
       
   108 		}
       
   109     TBool retValue = EFalse;
       
   110     TInt length = Max( aMimeHeaders.ContentType().Length() +
       
   111        aMimeHeaders.ContentSubType().Length() + 1, KMmsImportFileLength );
       
   112        		
       
   113     HBufC8* contentType = HBufC8::NewL( length );
       
   114     CleanupStack::PushL( contentType );   
       
   115 		
       
   116     contentType->Des().Copy( aMimeHeaders.ContentType() );
       
   117     contentType->Des().Append( KMmsSlash8 );
       
   118     contentType->Des().Append( aMimeHeaders.ContentSubType() );
       
   119     contentType->Des().LowerCase();
       
   120     
       
   121     TInt i = 0;
       
   122     CMetaDataArray* metaData = NULL;
       
   123     
       
   124     for ( i = 0; i < aMimeHeaders.ContentTypeParams().MdcaCount() - 1; i += KMms2 )
       
   125         {
       
   126         if ( aMimeHeaders.ContentTypeParams().MdcaPoint( i ).CompareF( KMmsForwardHeader ) == 0 
       
   127             && aMimeHeaders.ContentTypeParams().MdcaPoint( i + 1 ).CompareF( KMmsNoHeader ) == 0 )
       
   128             {
       
   129             metaData = CMetaDataArray::NewL();
       
   130             CleanupStack::PushL( metaData );
       
   131             metaData->AddL( KMmsContentTypeHeader , contentType->Des() );
       
   132             contentType->Des().Copy( KMmsDrmImportFile ); 
       
   133             }
       
   134         else if ( aMimeHeaders.ContentTypeParams().MdcaPoint( i ).
       
   135             CompareF( KMmsRingtoneHeader ) == 0 
       
   136             && aMimeHeaders.ContentTypeParams().MdcaPoint( i + 1 ).CompareF( KMmsNoHeader ) == 0 )
       
   137             {
       
   138             metaData = CMetaDataArray::NewL();
       
   139             CleanupStack::PushL( metaData );
       
   140             metaData->AddL( KMmsContentTypeHeader , contentType->Des() );
       
   141             contentType->Des().Copy( KMmsDrmImportFile ); 
       
   142             // Must also generate rights object and stream it into metadata
       
   143             //create rights
       
   144             CDRMRights* rights = CDRMRights::NewL();
       
   145             CleanupStack::PushL( rights );
       
   146             
       
   147             TInt size = 0;
       
   148             // Asset contains the content id
       
   149             // DrmAsset.h
       
   150             CDRMAsset* asset = CDRMAsset::NewLC();
       
   151             asset->iUid = KMmsHutchContentURI().AllocL(); // This will be freed by the assets destructor
       
   152             // Set the asset to the rights class, it will duplicate the asset
       
   153             rights->SetAssetL( *asset );
       
   154             size += KMmsAssetLength; // This is a guess, we don't know asset length.
       
   155             
       
   156             CleanupStack::PopAndDestroy( asset ); // Asset
       
   157             
       
   158             // DRMPermission.h
       
   159             CDRMPermission* permission = CDRMPermission::NewLC();
       
   160             // DRMConstraint.h
       
   161             // DRMTypes.h
       
   162             permission->iPlay = CDRMConstraint::NewL();
       
   163             permission->iDisplay = CDRMConstraint::NewL();
       
   164             permission->iExecute = CDRMConstraint::NewL();
       
   165             permission->iPrint = CDRMConstraint::NewL();
       
   166             permission->iAvailableRights = ERightsPlay | ERightsDisplay |
       
   167                 ERightsExecute | ERightsPrint;
       
   168             // major version for Oma 1 Rights Objects    
       
   169             permission->iRightsObjectVersion.iVersionMain = 1;
       
   170 
       
   171             // "ringtone=no" present 
       
   172             permission->iInfoBits = ENoRingingTone;
       
   173             permission->iOriginalInsertTime.UniversalTime();
       
   174             // Set top level and export to empty ones
       
   175             permission->iTopLevel = CDRMConstraint::NewL();
       
   176             permission->iExport = CDRMConstraint::NewL();
       
   177 
       
   178             // Set the permission to the rights class, it will duplicate the permission
       
   179             rights->SetPermissionL( *permission );
       
   180             
       
   181             size += permission->Size();
       
   182 
       
   183             CleanupStack::PopAndDestroy( permission ); // Permission
       
   184 
       
   185             // stream the rights into metadata
       
   186                 
       
   187             HBufC8* data = HBufC8::NewMaxLC( size );
       
   188 
       
   189             RMemWriteStream stream( (TAny*)( data->Ptr() ), size );
       
   190             CleanupClosePushL( stream );
       
   191 
       
   192             rights->ExternalizeL( stream );
       
   193             metaData->AddL( KOmaImportRightsField(), data->Des() );
       
   194     
       
   195             CleanupStack::PopAndDestroy( &stream ); // close stream
       
   196             CleanupStack::PopAndDestroy( data ); 
       
   197             
       
   198             CleanupStack::PopAndDestroy( rights );
       
   199             }
       
   200         }
       
   201     
       
   202     if ( iSupplier->IsImportSupported( contentType->Des() ) )
       
   203         {
       
   204         if ( !metaData )
       
   205             {
       
   206             metaData = CMetaDataArray::NewL();
       
   207             CleanupStack::PushL( metaData );
       
   208             }
       
   209         for ( i = 0; i < aMimeHeaders.XTypeParams().MdcaCount() - 1; i+= KMms2 )
       
   210             {
       
   211             metaData->AddL( aMimeHeaders.XTypeParams().MdcaPoint( i ),
       
   212                 aMimeHeaders.XTypeParams().MdcaPoint( i + 1 ) );
       
   213             }
       
   214         // Prepare agent for writing data 
       
   215         if ( iImportFile )
       
   216             {
       
   217             // invalid state, previous process not finished
       
   218             User::Leave( KErrArgument );
       
   219             }
       
   220     	iImportFile = iSupplier->ImportFileL( contentType->Des(), *metaData );
       
   221         retValue = ETrue;
       
   222         }
       
   223 
       
   224     if ( metaData )
       
   225         {
       
   226       	CleanupStack::PopAndDestroy( metaData );
       
   227         }
       
   228     CleanupStack::PopAndDestroy( contentType );
       
   229     return retValue;
       
   230 
       
   231     }
       
   232 
       
   233 // ---------------------------------------------------------
       
   234 //
       
   235 // ---------------------------------------------------------
       
   236 //
       
   237 void CMmsDrmCaf::StartProcessingL(
       
   238     RFile& aStartFile, const TDesC& aAttachmentFilePath, CMsvStore& aStore )
       
   239     {
       
   240     delete iAttachmentFilePath; // just in case the processing has been terminated incorreclty
       
   241     iAttachmentFilePath = NULL;
       
   242     iAttachmentFilePath = HBufC::NewL( aAttachmentFilePath.Length() );
       
   243     iAttachmentFilePath->Des().Copy( aAttachmentFilePath );
       
   244     iStore = &aStore;
       
   245     // We duplicate the handle, the caller may close its own copy
       
   246     iAttachmentFile.Duplicate( aStartFile );
       
   247     }
       
   248 
       
   249 
       
   250 // ---------------------------------------------------------
       
   251 //
       
   252 // ---------------------------------------------------------
       
   253 //
       
   254 TInt CMmsDrmCaf::WriteData( const TDesC8& aData )
       
   255     {
       
   256     TInt error = KErrNone;
       
   257     
       
   258     error = iImportFile->WriteData( aData );
       
   259     if ( error != KErrCANewFileHandleRequired )
       
   260         {
       
   261         // either all went well or the data was corrupted
       
   262         return error;
       
   263         }
       
   264         
       
   265     // We need a new file handle (error == KErrCANewFileHandleRequired)
       
   266     if ( iAttachmentFile.SubSessionHandle() )
       
   267         {
       
   268         // Caller provided open file handle
       
   269         error = iImportFile->ContinueWithNewOutputFile( iAttachmentFile,
       
   270             iAttachmentFilePath->Des() );
       
   271         // Close the caller's file handle as CAF has made a copy
       
   272         iAttachmentFile.Close();
       
   273         if ( error == KErrCANewFileHandleRequired )
       
   274             {
       
   275             TRAP( error, NewFileL() );
       
   276             }
       
   277         }
       
   278     else
       
   279         {
       
   280         TRAP( error, NewFileL() );
       
   281         }
       
   282     // We hope all went well    
       
   283     return error;
       
   284     }
       
   285 
       
   286 // ---------------------------------------------------------
       
   287 //
       
   288 // ---------------------------------------------------------
       
   289 //
       
   290 void CMmsDrmCaf::EndProcessingL()
       
   291     {
       
   292     TInt error = KErrNone;
       
   293     
       
   294     error = iImportFile->WriteDataComplete();
       
   295     if ( error == KErrCANewFileHandleRequired )
       
   296         {
       
   297         // CAF framework requires another file handle to finish the session
       
   298         TRAP( error, NewFileL() ); 
       
   299         }
       
   300         
       
   301     // We clean everything even in case of error
       
   302     delete iAttachmentFilePath;
       
   303     iAttachmentFilePath = NULL;
       
   304     // Terminate the session
       
   305     delete iImportFile;
       
   306     iImportFile = NULL;
       
   307     
       
   308     User::LeaveIfError( error );
       
   309     }
       
   310 
       
   311 // ---------------------------------------------------------
       
   312 //
       
   313 // ---------------------------------------------------------
       
   314 //
       
   315 void CMmsDrmCaf::NewFileL()
       
   316     {
       
   317     TInt error = KErrNone;
       
   318     TFileName* filename = new( ELeave )TFileName;
       
   319     CleanupStack::PushL( filename );
       
   320     
       
   321     do
       
   322         {
       
   323         if ( iImportFile->GetSuggestedOutputFileName( *filename ) != KErrNone )
       
   324             {
       
   325             TFileName* extension = new( ELeave )TFileName;
       
   326             CleanupStack::PushL( extension );
       
   327             _LIT( KDefAttName, "drmatt");
       
   328             *filename = KDefAttName;
       
   329             if ( iImportFile->GetSuggestedOutputFileExtension( *extension ) == KErrNone )
       
   330                 {
       
   331                 (*filename).Append( *extension );
       
   332                 }
       
   333             CleanupStack::PopAndDestroy( extension );
       
   334             }
       
   335 		CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
   336         RFile file;
       
   337    		iStore->CreateShareProtectedAttachmentL( *(filename), file, attachment );
       
   338 		error = iImportFile->ContinueWithNewOutputFile( file, attachment->FilePath() );
       
   339 		// import file duplicates the handle
       
   340         file.Close();
       
   341         } while  ( error == KErrCANewFileHandleRequired );
       
   342     
       
   343     CleanupStack::PopAndDestroy( filename );
       
   344     User::LeaveIfError( error );
       
   345     }
       
   346     
       
   347 
       
   348 //  End of File  
       
   349