profilesservices/MediaFileList/Src/mediafileprotection.cpp
branchRCL_3
changeset 25 7e0eff37aedb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/profilesservices/MediaFileList/Src/mediafileprotection.cpp	Wed Sep 01 12:20:44 2010 +0100
@@ -0,0 +1,625 @@
+/*
+* Copyright (c) 2007 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:   Class used to check the protection of the 
+*                media files.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+
+#include "mediafileprotection.h"
+#include "mediafilelist.h"
+#include "mediafilelistdebug.h"
+#include <mediafilelist.rsg>
+
+#include <DRMCommon.h>
+#include <drmutility.h>
+#include <drmagents.h>
+#include <bautils.h>
+#include <StringLoader.h>
+
+
+
+/******************************************************************************
+ * class CMFProtectionHandler
+ ******************************************************************************/
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::NewL
+//
+// -----------------------------------------------------------------------------
+CMFProtectionHandler* CMFProtectionHandler::NewL()
+    {
+    CMFProtectionHandler* self = new (ELeave) CMFProtectionHandler();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::CMFProtectionHandler
+// 
+// -----------------------------------------------------------------------------
+//
+CMFProtectionHandler::CMFProtectionHandler()
+	{
+	iMaxFileSize = KErrNotFound;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::CMFProtectionHandler
+//
+// -----------------------------------------------------------------------------
+//
+void CMFProtectionHandler::ConstructL()
+    {
+    iDriveUtil = CDriveUtil::NewL();
+    iVariation = CMediaFileDialogVariation::NewL();
+
+    iDRMHelper = CDRMHelper::NewL( *CCoeEnv::Static() );
+    
+    iDRMCommon = DRMCommon::NewL();
+    User::LeaveIfError( iDRMCommon->Connect() );
+    
+    iExcludedMimeTypes = CMimeTypeList::NewL();
+    
+    User::LeaveIfError( iApaLsSession.Connect() );
+    User::LeaveIfError( iFsSession.Connect() );
+    }
+
+
+// ----------------------------------------------------------------------------
+// Destructor
+//
+// ----------------------------------------------------------------------------
+//
+CMFProtectionHandler::~CMFProtectionHandler()
+    {
+    delete iDriveUtil;
+    delete iVariation;
+    
+    delete iDRMHelper;
+    
+    if ( iDRMCommon )
+        {
+        iDRMCommon->Disconnect(); // ignore possible error
+        delete iDRMCommon;
+        }
+    
+    delete iExcludedMimeTypes;
+    iApaLsSession.Close();
+    iFsSession.Close();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::SetAttr
+// 
+// -----------------------------------------------------------------------------
+void CMFProtectionHandler::SetAttrL( TInt aAttr, TInt aValue )
+    {
+    switch ( aAttr )
+        {
+        case CMediaFileList::EAttrFileSize:
+            {
+            iMaxFileSize = aValue;
+            break;
+            }
+        case CMediaFileList::EAttrAutomatedType:
+            {
+            iAutomatedType = (CDRMHelper::TDRMHelperAutomatedType) aValue;
+            break;
+            }
+
+        default:
+            {
+            break;
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::SetAttrL
+// 
+// -----------------------------------------------------------------------------
+void CMFProtectionHandler::SetAttrL( TInt aAttr, const TDesC& aValue )
+    {
+    if ( aAttr == CMediaFileList::EAttrExcludeMimeType )
+        {
+        if ( aValue.Length() > KMaxFileName || aValue.Length() == 0 )
+            {
+            User::Leave( KErrArgument );
+            }
+            
+        iExcludedMimeTypes->AddMimeTypeL( aValue );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsVideoValid
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsVideoValid( const TDesC& aFileName,
+                                         TIntention aIntention )
+    {
+    TInt err = KErrNone;
+    TBool ret = EFalse;
+    
+    TRAP( err, ret = IsVideoValidL (aFileName, aIntention ) )
+    
+    if ( err != KErrNone )
+        {
+        return EFalse;  // in case of error file is not valid
+        }
+    
+    return ret;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsVideoValidL
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsVideoValidL( const TDesC& aFileName,
+                                          TIntention /*aIntention*/ )
+    {
+    TBuf<KMaxDataTypeLength> dataType( DataTypeL( aFileName ).Des() );
+  
+    if ( iExcludedMimeTypes->FindMimeTypeL( dataType ) )
+        {
+        return EFalse;
+        }
+
+    CContent* content = CContent::NewLC( aFileName,
+                                         EContentShareReadWrite );
+    TInt deliveryMethod = 0;
+    content->GetAttribute( EDeliveryMethod, deliveryMethod );
+    
+    CleanupStack::PopAndDestroy( content );
+    
+    if( deliveryMethod == EOmaDrm2 )
+        {
+        // if video it is OMA DRM 2 protected, it cannot be previewed
+        return EFalse;
+        }
+    return ETrue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsFileValid
+// 
+// Checks protection state of media file. If this function returns EFalse,
+// media file cannot be used for playing/selection.
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsFileValid( const TDesC& aFileName,
+                                         TIntention aIntention )
+    {
+    TInt err = KErrNone;
+    TBool ret = EFalse;
+    
+    TRAP( err, ret = IsFileValidL (aFileName, aIntention ) )
+    
+    if ( err != KErrNone )
+        {
+        return EFalse;  // in case of error file is not valid
+        }
+    
+    return ret;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsFlieDRMExpired
+// 
+// Check if the DRM protect file is expired or have no rights.
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsFlieDRMExpired( const TDesC& aFileName )
+    {
+    // Check whether the file can be set as automated content or not
+    TBool canSetAutomated = EFalse;
+    TInt canSetAutomatedErr = iDRMHelper->CanSetAutomated( aFileName, canSetAutomated );
+    
+    // Check if rights expried or no rights to use
+    if ( canSetAutomatedErr == DRMCommon::ERightsExpired ||
+        canSetAutomatedErr == DRMCommon::ENoRights )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsFileValidL
+// 
+// Function is copy from CFLDDRMImplementation.cpp.
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsFileValidL( const TDesC& aFileName, 
+                                          TIntention aIntention )
+    {
+    TInt err = KErrNone;
+    TBuf<KMaxDataTypeLength> dataType( DataTypeL( aFileName ).Des() );
+    
+    if ( aFileName.Length() == 0 )
+        {
+        return ETrue;  // empty filename is valid??
+        }
+ 
+    if ( iExcludedMimeTypes->FindMimeTypeL( dataType ) )
+        {
+        ShowErrorNoteL( R_QTN_INFO_FILE_FORMAT_ERROR );
+        return EFalse;
+        }
+    
+    if ( aIntention == CMFProtectionHandler::ESelect && 
+        !CheckFileSize( aFileName, dataType ) )
+        {
+        HBufC* hBuf = StringLoader::LoadLC( R_QTN_INFO_FILE_SIZE_ERROR, iMaxFileSize );
+        TMFDialogUtil::ShowInformationNoteL( *hBuf );
+        CleanupStack::PopAndDestroy( hBuf );
+        return EFalse;
+        }
+
+    if ( iDriveUtil->IsRom( aFileName ) )
+        {
+        return ETrue;      // files in ROM are always valid
+        }
+
+    // check if file is WMDRM protected
+    TBool prot =  EFalse;
+    TRAP( err, prot = IsFileWMDRMProtectedL( aFileName ) );
+    if ( err != KErrNone )
+        {
+        ShowErrorNoteL( R_QTN_INFO_FILE_FORMAT_ERROR );
+        return EFalse;
+        }
+    if ( prot )
+        {
+        if ( aIntention == EPlay )
+            {
+            ShowErrorNoteL( R_QTN_INFO_DRM_PREV_RIGHTS_USE );
+            }
+        else
+            {
+            ShowErrorNoteL( R_QTN_INFO_DRM_PROTECTED );
+            }
+        return EFalse;
+        }
+
+    ContentAccess::TVirtualPathPtr path( aFileName,
+                        ContentAccess::KDefaultContentObject );
+    CData* data = CData::NewLC( path, EContentShareReadWrite );
+    TInt isProtected;
+    err = data->GetAttribute( EIsProtected, isProtected );
+    CleanupStack::PopAndDestroy( data );
+
+    if ( err != DRMCommon::EOk )
+        {
+        // DRM Helper class knows at least rights db corrupted error message.
+        // Leaves on system-wide error code.
+        iDRMHelper->HandleErrorL( err, aFileName );
+        return EFalse;
+        }
+
+    // Obtain information whether the file can be set as automated content
+    TBool canSetAutomated = EFalse;
+    TInt canSetAutomatedErr = 
+         iDRMHelper->CanSetAutomated( aFileName, canSetAutomated );
+
+    if ( !isProtected && canSetAutomated )
+        {
+        // The file in question is not DRM protected.
+        // Return ETrue if file is also Ok unprotected, otherwise EFalse.
+        TBool ret = IsFileValidUnprotectedL( aFileName, aIntention );
+        return ret;
+        }
+    
+    // Operator requirement: Check restrictions if file is mp4 audio
+    if ( iVariation->IsBlockedProtectedType( dataType ) )
+        {
+        ShowErrorNoteL( R_QTN_INFO_DRM_PROTECTED );
+        return EFalse;
+        }
+    
+    if ( canSetAutomatedErr == DRMCommon::ERightsExpired ||
+        canSetAutomatedErr == DRMCommon::ENoRights )
+        {
+        // Rights are expired, future rights or missing
+        iDRMHelper->HandleErrorL( canSetAutomatedErr, aFileName );
+        return EFalse;
+        }
+
+    // Operator requirement: Check DRM v2 tones
+    if ( !canSetAutomated )
+        {
+        // This is DRM v2 file OR count based v1 tone
+        if ( aIntention == EPlay )
+            {
+            ShowErrorNoteL( R_QTN_INFO_DRM_PREV_RIGHTS_USE );
+            }
+        else
+            {
+            ShowErrorNoteL( R_QTN_INFO_DRM_PROTECTED );
+            }
+        return EFalse;
+        }
+            
+    TInt32 infoBits( 0x00000000 );
+
+    // Find out rights information
+    if ( !GetFileInfoL( aFileName, infoBits ) )
+        {
+        // Corrupted file or "No rights" situation
+        return EFalse;
+        }
+
+    // Operator requirement: Check CFM protection
+    if ( infoBits & ENoRingingTone )
+        {
+        // This is CFM protected file, ringingtone is set to "no"
+        if ( aIntention == EPlay )
+            {
+            ShowErrorNoteL( R_QTN_INFO_DRM_PREV_RIGHTS_USE );
+            }
+        else
+            {
+            ShowErrorNoteL( R_QTN_INFO_DRM_PREV_RIGHTS_SET );
+            }
+        return EFalse;
+        }
+      
+    if ( aIntention == ESelect )
+        {
+        // Rights are good to go, and intention is selection
+        // call SetAutomatedPassive to show 'activation query' 
+        iDRMHelper->SetAutomatedType( iAutomatedType );
+        err = iDRMHelper->SetAutomatedPassive( aFileName );
+        if ( err != KErrCancel )
+            {
+            // User accepted dialog
+            User::LeaveIfError( err );
+            // New way, does not require DRM capability
+            data = CData::NewLC( path, EContentShareReadWrite );
+            err = data->ExecuteIntent( ContentAccess::EPlay );
+            // Wrongly requires DRM after all. According to Risto Vilkman
+            // from DRM, KErrAccessDenied can be ignored, since if
+            // CanSetAutomated says the tone is OK, it's OK.
+            if ( err != KErrNone && err != KErrAccessDenied )
+                {
+                User::Leave( err );
+                }
+            CleanupStack::PopAndDestroy( data );
+            }
+        else
+            {
+            // User canceled dialog
+            return EFalse;
+            }
+        }
+        
+    return ETrue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::GetFileInfo
+//
+// Function is copy from CFLDDRMImplementation.cpp.
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::GetFileInfoL( const TDesC& aFileName,
+                                          TInt32& aInfoBits )
+    {
+    DRMCommon::TContentProtection contentProtection; // ignored
+    HBufC8* mimeType = NULL; // ignored
+    TUint dataLength = 0; // ignored
+    HBufC8* contentURI = NULL;
+       
+    // Obtain content URI
+    TInt error = iDRMCommon->GetFileInfo(
+        aFileName, contentProtection, mimeType, contentURI, dataLength );
+    delete mimeType;
+
+    if ( error != DRMCommon::EOk )
+        {
+        delete contentURI;
+        // Handle possible corrupt file situation
+        iDRMHelper->HandleErrorL( error, aFileName );
+        return EFalse;
+        }
+
+    // Obtain rights object
+    CDRMRights* rights = NULL;
+    error = iDRMCommon->GetActiveRights( *contentURI, DRMCommon::EPlay, rights );
+    delete contentURI;
+
+    if ( error == DRMCommon::ENoRights )
+        {
+        delete rights;
+        // There is no rights for given file
+        // Should never arrive here, ENoRights is handled
+        // already in IsFileValidL()
+        iDRMHelper->HandleErrorL( error, aFileName );
+        return EFalse;
+        }
+     
+    // Obtain infobits ( needed only for CFM case )     
+   aInfoBits = rights->GetPermission().iInfoBits;
+   delete rights;
+   return ETrue;
+   }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsFileWMDRMProtectedL
+//
+// Function is copy from CFLDDRMImplementation.cpp.
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsFileWMDRMProtectedL( const TDesC& aFileName )
+    {
+    TBool res = EFalse;
+    RFile hFile;
+
+    TInt err = hFile.Open( iFsSession, aFileName, 
+                           EFileRead | EFileStream | EFileShareReadersOnly );
+    if ( err == KErrInUse )
+        {
+        err = hFile.Open( iFsSession, aFileName, 
+                        EFileRead | EFileStream | EFileShareAny );
+        }
+    if ( err != KErrNone )
+        {
+        User::Leave( err );
+        }
+    CleanupClosePushL( hFile );
+
+    TPtrC agent( KNullDesC );
+    DRM::CDrmUtility* drmUtil = DRM::CDrmUtility::NewLC();
+    drmUtil->GetAgentL( hFile, agent );
+    if ( agent.Compare( DRM::KDrmWMAgentName ) == 0 )
+        {
+        res = ETrue;
+        }
+    CleanupStack::PopAndDestroy( drmUtil );
+
+    CleanupStack::PopAndDestroy( &hFile );
+    return res;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::DataTypeL
+//
+// Function is copy from CFLDDRMImplementationCommon.cpp.
+// -----------------------------------------------------------------------------
+//
+TDataType CMFProtectionHandler::DataTypeL( const TDesC& aFileName )
+    {
+    TUid dummyUid = { 0 };
+    TDataType dataType( dummyUid );
+    User::LeaveIfError(
+        iApaLsSession.AppForDocument( aFileName, dummyUid, dataType ) );
+
+    return dataType;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::IsFileValidUnprotectedL
+// 
+// Function is copy from CFLDDRMImplementationCommon.cpp.
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::IsFileValidUnprotectedL( const TDesC& aFileName,
+                                                     TIntention aIntention )
+    {
+    TDataType dataType = DataTypeL( aFileName );
+    TBuf<KMaxDataTypeLength> mimeType;
+    
+    mimeType = dataType.Des();
+
+    if ( iVariation->IsBlockedType( mimeType ) )
+        {
+        if ( aIntention == ESelect )
+            {
+            ShowErrorNoteL( R_QTN_INFO_TEXT_NOT_ALLOWED );
+            }
+        return EFalse;
+        }
+
+    // Operator requirement. Check if DRM is required with tones.
+    if ( aIntention == EPlay )
+        {
+        if ( iVariation->IsBlockedDemoPlayType( mimeType ) )
+            {
+            return EFalse;
+            }
+        }
+    else
+        {
+        if ( iVariation->IsBlockedUnprotectedType( mimeType ) )
+            {
+            ShowErrorNoteL( R_QTN_INFO_NO_DRM );
+            return EFalse;
+            }
+        }
+
+    return ETrue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::CheckFileSize
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMFProtectionHandler::CheckFileSize( const TDesC& aFile, const TDesC& aMimeType  )
+    {
+    _LIT( KVideo, "video" );
+    const TInt KKiloByte = 1024;
+    const TInt KSmallSize = 10;
+   
+    if ( iMaxFileSize < KSmallSize )
+        {
+        return ETrue; // too small size limit
+        }
+    if ( aMimeType.Find( KVideo ) != KErrNotFound )
+        {
+        return ETrue;  // only audio files are checked
+        }
+    
+    TEntry entry;
+    TInt err = iFsSession.Entry( aFile, entry );
+    if ( err == KErrNone && iMaxFileSize != KErrNotFound )
+        {
+        TInt size = iMaxFileSize * KKiloByte; // KBytes -> Bytes
+        if ( entry.iSize > size )
+            {
+            return EFalse;
+            }
+        }
+  
+    return ETrue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMFProtectionHandler::ShowErrorNoteL
+// 
+// -----------------------------------------------------------------------------
+//
+void CMFProtectionHandler::ShowErrorNoteL( TInt aResourceId )
+    {
+    TMFDialogUtil::ShowInformationNoteL( aResourceId );
+    }
+
+
+//  End of File