commondrm/drmutility/src/DrmUtilityDmgrWrapper.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 15 Mar 2010 12:41:43 +0200
branchRCL_3
changeset 18 8a03a285ab14
parent 0 95b198f216e5
child 71 1221b68b8a5f
permissions -rw-r--r--
Revision: 201009 Kit: 201010

/*
* Copyright (c) 2007-2008 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:  Dynamically loadable wrapper for Download manager
*
*/

#include <centralrepository.h>
#include <cdblen.h>
#include <cmconnectionmethod.h>
#include <cmdestination.h>
#include <cmconnectionmethoddef.h>
#include <cmmanager.h>

#ifdef __SERIES60_NATIVE_BROWSER
#include <browseruisdkcrkeys.h>
#endif

#ifdef RD_MULTIPLE_DRIVE
#include <driveinfo.h>
#endif

#include <StringLoader.h>
#include <data_caging_path_literals.hrh>

#include <ConeResLoader.h>
#include <apparc.h>
#include <DrmUtilityDmgrWrapper.rsg>

#include "RoapEng.h"
#include "RoapSyncWrapper.h"
#include "RoapDef.h"

#include "DrmUtilityDmgrWrapper.h"
#include "DrmUtilityDmgrWrapperLogger.h"

// DEBUG macros
#ifdef _DEBUG
#define DRMDEBUGLIT( a, b ) \
_LIT( a , b )
#define DRMDEBUG( a ) \
RDebug::Print( a )
#define DRMDEBUG2( a, b ) \
RDebug::Print( a, b )
#else
#define DRMDEBUGLIT( a, b )
#define DRMDEBUG( a )
#define DRMDEBUG2( a, b )
#endif

// CONSTANTS
#ifndef __SERIES60_NATIVE_BROWSER
const TUid KCRUidBrowser = {0x10008D39};
const TUint32 KBrowserDefaultAccessPoint = 0x0000000E;
const TUint32 KBrowserAccessPointSelectionMode = 0x0000001E;
#endif

#ifndef RD_MULTIPLE_DRIVE
_LIT( KDriveZ, "z:" );
_LIT( KDrmUtilityTriggerFilePath, "d:\\" );
#else
_LIT( KRomDriveFormatter, "%c:" );
_LIT( KKDrmUtilityTriggerFilePathFormatter, "%c:\\" );
#endif

_LIT( KCDrmUtilityDmgrWrapperResFileName,"DrmUtilityDmgrWrapper.rsc" );
const TInt KProgressInfoFinalValue( 200 );
const TInt KProgressInfoIncrementSmall( 5 );
const TInt KProgressInfoIncrementMedium( 10 );
const TInt KProgressInfoIncrementLarge( 30 );

// ======== LOCAL FUNCTIONS ========

// ---------------------------------------------------------------------------
// DeleteHttpDowload
// ---------------------------------------------------------------------------
//
LOCAL_C void DeleteHttpDowload( TAny* aDownload )
    {
    reinterpret_cast< RHttpDownload* >( aDownload )->Delete();
    }

// ---------------------------------------------------------------------------
// IapIdOfDefaultSnapL
// for trapping purposes only
// ---------------------------------------------------------------------------
//
LOCAL_C TUint32 IapIdOfDefaultSnapL(
    RCmManager& aCmManager,
    const TUint32 aDefaultSnap )
    {
    RCmDestination dest( aCmManager.DestinationL( aDefaultSnap ) );
    CleanupClosePushL( dest );
    TUint32 iapIdOfDest( 0 );

    if ( dest.ConnectionMethodCount() <= 0 )
        {
        User::Leave( KErrNotFound );
        }

    RCmConnectionMethod cMeth( dest.ConnectionMethodL( 0 ) );
    CleanupClosePushL( cMeth );

    iapIdOfDest = cMeth.GetIntAttributeL( CMManager::ECmIapId );
    CleanupStack::PopAndDestroy( &cMeth );
    CleanupStack::PopAndDestroy( &dest );
    return iapIdOfDest;
    }


// ======== MEMBER FUNCTIONS ========

// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::CDrmUtilityDmgrWrapper
// ---------------------------------------------------------------------------
//
CDrmUtilityDmgrWrapper::CDrmUtilityDmgrWrapper() :
    iUseCoeEnv( EFalse )
    {
    }

// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::ConstructL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::ConstructL()
    {
    CLOG_WRITE( "DMgrWrapper::ConstructL" );
    const TInt KDrmUtilityDmgrWrapperUid = 0x102830FE;
    iDlMgr.ConnectL( TUid::Uid(KDrmUtilityDmgrWrapperUid), *this, EFalse );
    iProgressInfo = NULL;
    iProgressNoteDialog = NULL;
    iDialogDismissed = ETrue;
    }



// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::NewL
// ---------------------------------------------------------------------------
//
CDrmUtilityDmgrWrapper* CDrmUtilityDmgrWrapper::NewL()
    {
    CLOG_WRITE( "DMgrWrapper::NewL" );
    CDrmUtilityDmgrWrapper* self( CDrmUtilityDmgrWrapper::NewLC() );
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::NewLC
// ---------------------------------------------------------------------------
//
CDrmUtilityDmgrWrapper* CDrmUtilityDmgrWrapper::NewLC()
    {
    CLOG_WRITE( "DMgrWrapper::NewLC" );
    CDrmUtilityDmgrWrapper* self( new( ELeave ) CDrmUtilityDmgrWrapper() );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::~CDrmUtilityDmgrWrapper
// ---------------------------------------------------------------------------
//
CDrmUtilityDmgrWrapper::~CDrmUtilityDmgrWrapper()
    {
    CLOG_WRITE( "DMgrWrapper destructor" );
    if ( iProgressNoteDialog )
       {
       // deletes the dialog
       TRAPD( err, iProgressNoteDialog->ProcessFinishedL() );
       if ( err )
           {
           delete iProgressNoteDialog;
           }
       iProgressNoteDialog = NULL;
       }
    delete iErrorUrl;
    delete iPostResponseUrl;

#ifdef _DEBUG

    if ( iDlMgr.Handle() )
        {
        iDlMgr.Close();
        }

#else

    iDlMgr.Close();

#endif
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::DownloadAndHandleRoapTriggerL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::DownloadAndHandleRoapTriggerL( const HBufC8* aUrl )
    {
    CLOG_WRITE( "DMgrWrapper::DownloadAndHandleRoapTriggerL" );
    iUseCoeEnv = EFalse;
    DoDownloadAndHandleRoapTriggerL( aUrl );
    HandlePostResponseUrlL();
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::DownloadAndHandleRoapTriggerL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::DownloadAndHandleRoapTriggerL(
    const HBufC8* aUrl, CCoeEnv& aCoeEnv )
    {
    CLOG_WRITE( "DMgrWrapper::DownloadAndHandleRoapTriggerL" );
    iCoeEnv = &aCoeEnv;
    iUseCoeEnv = ETrue;
    DoDownloadAndHandleRoapTriggerL( aUrl );
    HandlePostResponseUrlL();
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::HandlePostResponseUrlL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::HandlePostResponseUrlL()
    {
    if ( iPostResponseUrl )
        {
        DoDownloadAndHandleRoapTriggerL( iPostResponseUrl );
        // prevent infinite post response fetches.
        delete iPostResponseUrl;
        iPostResponseUrl = NULL;

        // Ensure progress note gets deleted.
        // It remains open if prUrl initialted ROAP operation has PrUrl
        // (unsupported chained metering report)
        RemoveProgressNoteL();
        }
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::DoDownloadAndHandleRoapTriggerL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::DoDownloadAndHandleRoapTriggerL(
    const HBufC8* aUrl )
    {
    RFs fs;
    RFile roapTrigger;
    HBufC8* triggerBuf( NULL );
    TBool result( EFalse );
    TFileName triggerFileName;

    CLOG_WRITE( "DMgrWrapper::DoDownloadAndHandleRoapTriggerL" );
    User::LeaveIfError( fs.Connect() );
    CleanupClosePushL( fs );
    User::LeaveIfError( fs.ShareProtected() );

#ifndef RD_MULTIPLE_DRIVE

    User::LeaveIfError( roapTrigger.Temp(
            fs, KDrmUtilityTriggerFilePath, triggerFileName, EFileWrite ) );

#else //RD_MULTIPLE_DRIVE

    TInt driveNumber( -1 );
    TChar driveLetter;
    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRam, driveNumber );
    fs.DriveToChar( driveNumber, driveLetter );

    TFileName utilityTriggerFilePath;

    utilityTriggerFilePath.Format( KKDrmUtilityTriggerFilePathFormatter,
        (TUint)driveLetter );

    User::LeaveIfError( roapTrigger.Temp(
            fs, utilityTriggerFilePath, triggerFileName, EFileWrite ) );

#endif


    TPtrC8 KNullPtr8( NULL, 0 );
    RHttpDownload* downloadPtr( iDlMgr.FindDownload( *aUrl, KNullPtr8 ) );
    if ( downloadPtr )
        {
        // Stale download found.
        // Remove it, and re-create a new download.
        downloadPtr->Delete();
        downloadPtr = NULL;
        }

    // create and start download
    RHttpDownload& download = iDlMgr.CreateDownloadL( *aUrl, result );
    // Put download for proper cleanup.
    TCleanupItem item( DeleteHttpDowload, &download );
    CleanupStack::PushL( item );

    CleanupClosePushL( roapTrigger );

    if ( !iPostResponseUrl )
        {
        // No post response retieval. Note must be created.
        ShowProgressNoteL();
        }

    if ( result )
        {
        const TInt KReadBufSize( 512 );
        TInt triggerFileSize( 0 );

        CLOG_WRITE(
            "DMgrWrapper::DoDownloadAndHandleRoapTriggerL: download created" );
        iDownloadSuccess = EFalse;
        iConnectionError = EFalse;

        SetDefaultAccessPointL();

        User::LeaveIfError( download.SetFileHandleAttribute( roapTrigger ) );
        User::LeaveIfError(
            download.SetBoolAttribute( EDlAttrNoContentTypeCheck, ETrue ) );
        User::LeaveIfError( download.Start() );

        // wait until download is finished
        iWait.Start();

        // Check success of download
        CLOG_WRITE(
            "DMgrWrapper::DoDownloadAndHandleRoapTriggerL: download finished" );

        CleanupStack::Pop( &roapTrigger );
        roapTrigger.Close();
        if ( !iDownloadSuccess )
            {
            RemoveProgressNoteL();
            if ( iConnectionError )
                {
                User::Leave( KErrCouldNotConnect );
                }
            else
                {
                User::Leave( KErrGeneral );
                }
            }
        User::LeaveIfError( roapTrigger.Open( fs,
                                              triggerFileName,
                                              EFileShareReadersOrWriters ) );
        CleanupClosePushL( roapTrigger );

        // Get filehandle of ROAP trigger
        // Read file to buffer
        User::LeaveIfError( roapTrigger.Size( triggerFileSize ) );
        triggerBuf = HBufC8::NewLC( triggerFileSize );

        RBuf8 readBuf;
        readBuf.CleanupClosePushL();
        readBuf.CreateL( KReadBufSize );

        User::LeaveIfError( roapTrigger.Read( readBuf, KReadBufSize ) );
        triggerBuf->Des().Copy( readBuf );
        while ( readBuf.Length() == KReadBufSize )
            {
            User::LeaveIfError( roapTrigger.Read( readBuf, KReadBufSize ) );
            triggerBuf->Des().Append( readBuf );
            }

        CleanupStack::PopAndDestroy( &readBuf );

        if ( iUseCoeEnv && iProgressInfo )
            {
            iProgressInfo->IncrementAndDraw( KProgressInfoIncrementMedium );
            }

        // And let ROAP handle it...
        CRoapSyncWrapper* roapWrapper( CRoapSyncWrapper::NewL() );
        CleanupStack::PushL( roapWrapper );
        TRAPD( err, roapWrapper->HandleTriggerL( *triggerBuf ) );
        if ( err )
            {
            TInt errorType( 0 );
            TRAPD( err2,
                iErrorUrl = roapWrapper->GetErrorUrlL( err, errorType ) );
            if ( err2 )
                {
                RemoveProgressNoteL();
                delete iErrorUrl;
                iErrorUrl = NULL;
                User::Leave( err2 );
                }
            else if ( errorType != KErrRoapTemporary )
                {
                RemoveProgressNoteL();
                delete iErrorUrl;
                iErrorUrl = NULL;
                User::Leave( err );
                }
            else
                {
                RemoveProgressNoteL();
                User::Leave( err );
                }
            }
        if ( iPostResponseUrl )
            {
            delete iPostResponseUrl;
            iPostResponseUrl = NULL;
            }
        iPostResponseUrl = roapWrapper->GetPostResponseUrlL();
        CleanupStack::PopAndDestroy( 2, triggerBuf );

        if ( iUseCoeEnv && iProgressInfo && !iPostResponseUrl )
            {
            // No PrUrl found. Progess is complete.
            iProgressInfo->SetAndDraw( KProgressInfoFinalValue );
            }
        }

    // Trick to keep note open long enough during prUrl retrieval
    if ( !iPostResponseUrl )
        {
        RemoveProgressNoteL();
        }
    else
        {
        if ( iUseCoeEnv && iProgressInfo )
            {
            iProgressInfo->IncrementAndDraw( KProgressInfoIncrementMedium );
            }
        }

    CleanupStack::PopAndDestroy( &roapTrigger );
    CleanupStack::PopAndDestroy( &download );

    fs.Delete( triggerFileName );
    CleanupStack::PopAndDestroy( &fs );
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::SetDefaultAccessPointL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::SetDefaultAccessPointL()
    {
    const TInt KDestinationSelectionMode( 2 );
    CRepository* repository( NULL );
    TInt ap( 0 );
    TInt alwaysAsk( 0 );
    TUint32 iapd32( 0 );
    TInt defaultSnap( 0 );
    TInt err( KErrNone );

    CLOG_WRITE( "DMgrWrapper::SetDefaultAccessPointL" );
    DRMDEBUGLIT( KDuiBrApFormat,
        "CDrmUtilityDmgrWrapper::SetDefaultAccessPointL %d" );
    DRMDEBUGLIT( KDuiBrApFormat2, " KBrowserDefaultAccessPoint = %d" );
    DRMDEBUGLIT( KDuiBrApFormat3, " KBrowserAccessPointSelectionMode = %d" );
    DRMDEBUGLIT( KDuiBrApFormat4, " KBrowserNGDefaultSnapId = %d" );

    repository = CRepository::NewL( KCRUidBrowser );
    CleanupStack::PushL( repository );
    repository->Get( KBrowserDefaultAccessPoint, ap );
    repository->Get( KBrowserAccessPointSelectionMode, alwaysAsk );
    repository->Get( KBrowserNGDefaultSnapId, defaultSnap );
    DRMDEBUG2( KDuiBrApFormat(), __LINE__ );
    DRMDEBUG2( KDuiBrApFormat2(), ap );
    DRMDEBUG2( KDuiBrApFormat3(), alwaysAsk );
    DRMDEBUG2( KDuiBrApFormat4(), defaultSnap );

    if ( ap <= KErrNotFound && defaultSnap <= KErrNotFound )
        {
        alwaysAsk = ETrue;
        }
    else
        {
        RCmManager cmManager;
        cmManager.OpenLC();
        if ( !alwaysAsk )
            {
            TRAP( err, iapd32 = cmManager.GetConnectionMethodInfoIntL(
                    ap, CMManager::ECmIapId ) );
            }
        else if ( alwaysAsk == KDestinationSelectionMode )
            {
            TRAP( err, iapd32 =
                IapIdOfDefaultSnapL( cmManager, defaultSnap ) );
            }
        CleanupStack::PopAndDestroy( &cmManager );
        }
    if ( !err && ( !alwaysAsk || alwaysAsk == KDestinationSelectionMode ) )
        {
        err = iDlMgr.SetIntAttribute( EDlMgrIap, iapd32 );
        }
    CleanupStack::PopAndDestroy( repository );
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::GetErrorUrlL
// ---------------------------------------------------------------------------
//
HBufC8* CDrmUtilityDmgrWrapper::GetErrorUrlL()
    {
    if( iErrorUrl )
        {
        return iErrorUrl->AllocL();
        }
    return NULL;
    }


// ---------------------------------------------------------------------------
// From class MHttpDownloadMgrObserver
//
// CDrmUtilityDmgrWrapper::HandleDMgrEventL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::HandleDMgrEventL(
    RHttpDownload& aDownload,
    THttpDownloadEvent aEvent )
    {
    _LIT8( KDrmUtilityMimeTypeROAPTrigger,
        "application/vnd.oma.drm.roap-trigger+xml" );

    CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL" );
    CLOG_WRITE_FORMAT( "iDownLoadState = %d", aEvent.iDownloadState );
    CLOG_WRITE_FORMAT( "iProgressState = %d", aEvent.iProgressState );

    if ( aEvent.iProgressState == EHttpContentTypeReceived )
        {
        // check received mimetype
        RBuf8 contentType;
        contentType.CleanupClosePushL();
        contentType.CreateL( KMaxContentTypeLength );
        User::LeaveIfError(
            aDownload.GetStringAttribute( EDlAttrContentType, contentType ) );
        if ( !contentType.FindF( KDrmUtilityMimeTypeROAPTrigger ) )
            {
            // ROAP trigger found, continue download
            User::LeaveIfError( aDownload.Start() );
            }
        else
            {
            // wrong MIME type, so stop download
            iDownloadSuccess = EFalse;
            User::LeaveIfError( aDownload.Delete() );
            }
        CleanupStack::PopAndDestroy( &contentType );
        }

    if ( aEvent.iDownloadState == EHttpDlCreated )
        {
        CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL: EHttpDlCreated" );
        if ( iUseCoeEnv )
            {
        iProgressInfo->IncrementAndDraw( KProgressInfoIncrementMedium );
            }
        }
    else if ( aEvent.iProgressState == EHttpProgDisconnected )
        {
        CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL: EHttpProgDisconnected" );
        // store failure
        iDownloadSuccess = EFalse;
        iConnectionError = ETrue;
        // finished
        iWait.AsyncStop();
        }
    else if ( aEvent.iDownloadState == EHttpDlInprogress )
        {
        CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL: EHttpDlInprogress" );
        if ( iUseCoeEnv )
            {
        iProgressInfo->IncrementAndDraw( KProgressInfoIncrementSmall );
            }
        }
    else if ( aEvent.iDownloadState == EHttpDlCompleted )
        {
        // store success
        CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL: EHttpDlCompleted" );
        iDownloadSuccess = ETrue;
        if ( iUseCoeEnv )
            {
        iProgressInfo->IncrementAndDraw( KProgressInfoIncrementLarge );
            }
        // finished
        iWait.AsyncStop();
        }
    else if ( aEvent.iDownloadState == EHttpDlFailed )
        {
        TInt32 err( KErrNone );

        CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL: EHttpDlFailed" );
        // store failure
        iDownloadSuccess = EFalse;
        User::LeaveIfError( aDownload.GetIntAttribute( EDlAttrErrorId, err ) );
        CLOG_WRITE_FORMAT( "EDlAttrErrorId = %d", err );

        if ( err == EConnectionFailed ||
             err == ETransactionFailed)
            {
            CLOG_WRITE( "DMgrWrapper::HandleDMgrEventL: EConnectionFailed" );
            iConnectionError = ETrue;
            }

        // finished
        iWait.AsyncStop();
        }
    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::ShowProgressNoteL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::ShowProgressNoteL()
    {
    TFileName resFileName;

    CLOG_WRITE( "DMgrWrapper::ShowProgressNoteL" );
    if ( iUseCoeEnv )
        {
        // Initialize the progress note dialog, it's values,
        // and execute it
#ifndef RD_MULTIPLE_DRIVE

        resFileName.Copy( KDriveZ );

#else //RD_MULTIPLE_DRIVE

        TInt driveNumber( -1 );
        TChar driveLetter;
        DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, driveNumber );

        iCoeEnv->FsSession().DriveToChar( driveNumber, driveLetter );

        resFileName.Format( KRomDriveFormatter, (TUint)driveLetter );

#endif

        resFileName.Append( KDC_RESOURCE_FILES_DIR );
        resFileName.Append( KCDrmUtilityDmgrWrapperResFileName );
        RConeResourceLoader loader( *iCoeEnv );
        loader.OpenL( resFileName );

        iProgressNoteDialog = new (ELeave) CAknProgressDialog(
            reinterpret_cast< CEikDialog** >( &iProgressNoteDialog ) );
        iProgressNoteDialog->PrepareLC( R_SILENT_PROGRESS_NOTE );
        iProgressNoteDialog->SetCallback( this );
        iProgressInfo = iProgressNoteDialog->GetProgressInfoL();
        iProgressInfo->SetFinalValue( KProgressInfoFinalValue );
        iDialogDismissed = EFalse;
        iProgressNoteDialog->RunLD();

        loader.Close();
        }

    }


// ---------------------------------------------------------------------------
// CDrmUtilityDmgrWrapper::RemoveProgressNoteL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::RemoveProgressNoteL()
    {

    if ( iUseCoeEnv )
        {
        if (iProgressNoteDialog && !iDialogDismissed)
            {
            // deletes the dialog
            TRAPD(err, iProgressNoteDialog->ProcessFinishedL());
            if (err != KErrNone)
                {
                delete iProgressNoteDialog;
                }
            iProgressNoteDialog = NULL;
            }
        }

    }


// ---------------------------------------------------------------------------
// From class MAknProgressDialogCallback
//
// CDrmUtilityDmgrWrapper::DialogDismissedL
// ---------------------------------------------------------------------------
//
void CDrmUtilityDmgrWrapper::DialogDismissedL( TInt /*aButtonId*/ )
    {
    iDialogDismissed = ETrue;

    // Already freed, just set to NULL
    iProgressNoteDialog = NULL;
    iProgressInfo = NULL;

    if( iWait.IsStarted() )
        {
        iWait.AsyncStop();
        }

    }


// ======== GLOBAL FUNCTIONS ========

//------------------------------------------------------------------------------
// GateFunctionDRM
// DRM gate function
//------------------------------------------------------------------------------
EXPORT_C TAny* GateFunctionDMgr()
    {
    CDrmUtilityDmgrWrapper* launcher = NULL;
    TRAPD( err, launcher = CDrmUtilityDmgrWrapper::NewL() );
    if( err != KErrNone )
        {
        return NULL;
        }

    return launcher;
    }