/*
* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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:  User Interactions event handler
*
*/

// INCLUDE FILES
#include    <browser_platform_variant.hrh>
#include    "UserInteractionsEventHandler.h"
#include    "CUserInteractionsUtils.h"
#include    "ProgressInfoCreator.h"
#include    <cdownloadmgruilibregistry.h>
#include    <cdownloadmgruidownloadslist.h>
#include    <cdownloadmgruiuserinteractions.h>
#include    "UiLibLogger.h"
#include    "DMgrUiLibPanic.h"
#include    <bldvariant.hrh>
#include    <DownloadMgrUiLib.rsg>
#include    <aknlists.h>
#include    <aknPopup.h>
#include    <StringLoader.h>
#include    <apgcli.h>
#include    <eikbtgpc.h>
#include    <SysUtil.h>
#include    <exterror.h>
#include    <etelpckt.h>
#include    <AknNoteDialog.h>
#include    <UriUtils.h>

#ifdef BRDO_APP_GALLERY_SUPPORTED_FF
#include    <MGXFileManagerFactory.h>
#include    <CMGXFileManager.h>
#endif

#include    <pathinfo.h>
#include    <driveinfo.h>

#include    <apmrec.h>
#include    <apmstd.h>
#include    <s32std.h>
#include    <e32des8.h>

#include    <AiwGenericParam.h>
#include    <DocumentHandler.h>


// LOCAL CONSTANTS AND MACROS
_LIT( KListBoxSeparator, "\t" );
_LIT( KDownloadPath,"download");


const TInt KDownloadConfSizeLimit = 100000;

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

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::CUserInteractionsEventHandler
// -----------------------------------------------------------------------------
//
CUserInteractionsEventHandler::CUserInteractionsEventHandler
    ( RHttpDownload& aDownload, THttpDownloadEvent aEvent, 
      MDownloadMgrUiLibRegModel& aRegistryModel, 
      CAsyncEventHandlerArray& aOwner,
      CUserInteractionsUtils& aUiUtils )
:   CAsyncEventHandlerBase( aDownload, aEvent, aRegistryModel, aOwner ),
    iUiUtils( aUiUtils ),
    iDownloadConfirmationShown( EFalse )
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::CUserInteractionsEventHandler");
    CLOG_WRITE_FORMAT(" %x", this);
    CLOG_LEAVEFN("CUserInteractionsEventHandler::CUserInteractionsEventHandler");
    }

// Destructor
CUserInteractionsEventHandler::~CUserInteractionsEventHandler()
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::~CUserInteractionsEventHandler");
    CLOG_WRITE_FORMAT(" %x", this);
    if ( iPopupList )
        {
        iPopupList->CancelPopup();
        iPopupList = NULL;
        }
    if ( iDeletedPtr )
        {
        *iDeletedPtr = ETrue;
        }
    if ( iDownloadConfirmationDeletedPtr )
        {
        *iDownloadConfirmationDeletedPtr = ETrue;
        }
    Cancel();
    CLOG_LEAVEFN("CUserInteractionsEventHandler::~CUserInteractionsEventHandler");
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::DiskSpaceBelowCriticalLevelL
// -----------------------------------------------------------------------------
//
#ifdef RD_MULTIPLE_DRIVE
TBool CUserInteractionsEventHandler::DiskSpaceBelowCriticalLevelL( RHttpDownload& aDownload, TInt aSize ) const
#else
TBool CUserInteractionsEventHandler::DiskSpaceBelowCriticalLevelL( TInt aSize ) const
#endif
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::DiskSpaceBelowCriticalLevelL");

   	TBool isSpaceBelowCL( EFalse );

    RFs fs;
    User::LeaveIfError( fs.Connect() );
    CleanupClosePushL( fs );
    
    TInt bytesToWrite = aSize;
    if (bytesToWrite < 0)
        bytesToWrite = 0;

#ifdef RD_MULTIPLE_DRIVE
    // Destination is FFS in default
    TInt selectedDrive;
    User::LeaveIfError(
        DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory,
                                    selectedDrive ) );
    TInt err( KErrNone );

    HBufC* fileName = HBufC::NewLC( KMaxPath );
    TPtr fileNamePtr = fileName->Des();
    User::LeaveIfError
        ( aDownload.GetStringAttribute( EDlAttrDestFilename, fileNamePtr ) );
    CLOG_WRITE_FORMAT(" EDlAttrDestFilename: %S",&fileNamePtr);

    // only that drive needs to be checked
    CLOG_WRITE( "cfds1" );
    if( (err = fs.CharToDrive( (*fileName)[0], selectedDrive )) != KErrNone )
        {
        CLOG_WRITE( "Bad drive letter" );
        User::Leave( err );
        }
    else if( !fs.IsValidDrive( selectedDrive ) )
        // invalid drive letter in filename
        {
        CLOG_WRITE( "Invalid drive" );
        User::Leave( KErrBadName );
        }

    CleanupStack::PopAndDestroy( fileName ); // fileName
    fileName = NULL;

    // Check if there's enough memory in the phone
	TRAP_IGNORE( isSpaceBelowCL = SysUtil::DiskSpaceBelowCriticalLevelL(
                                            &fs,
                                            bytesToWrite,
                                            selectedDrive ) );

    // If there is error, then isSpaceBelowCL is untouched and 
    // contains the right value. Otherwise it also contains 
    // the right value.
    CLOG_WRITE_FORMAT(" DiskSpace: isSpaceBelowCL: %d",isSpaceBelowCL);

#else
	isSpaceBelowCL = SysUtil::DiskSpaceBelowCriticalLevelL( &fs, 
			                                bytesToWrite,
                                            EDriveC );
    CLOG_WRITE_FORMAT(" C: isSpaceBelowCL: %d",isSpaceBelowCL);

    if ( isSpaceBelowCL )
        {
        // Check MMC
        TRAP_IGNORE( isSpaceBelowCL = 
                     SysUtil::MMCSpaceBelowCriticalLevelL( &fs, bytesToWrite ) );
        // If there is error, then isSpaceBelowCL is untouched and 
        // contains the right value. Otherwise it also contains 
        // the right value.
        CLOG_WRITE_FORMAT(" MMC: isSpaceBelowCL: %d",isSpaceBelowCL);
        }
#endif

    CleanupStack::PopAndDestroy( &fs ); // fs

    CLOG_LEAVEFN("CUserInteractionsEventHandler::DiskSpaceBelowCriticalLevelL");
    return isSpaceBelowCL;
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::ShowDownloadConfirmationL
// Confirmation is not shown, if:
// - the downloaded size = total size
// - or the total size is less than 100 kB
// The confirmation query is shown, if aForce is ETrue!
// -----------------------------------------------------------------------------
//
TBool CUserInteractionsEventHandler::ShowDownloadConfirmationL
    ( RHttpDownload& aDownload, TInt aCbaResource, TBool aForce )
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::ShowDownloadConfirmationL aForce");

    TBool ret;
    if ( aForce )
        {
        ret = ShowDownloadConfirmationL( aDownload, aCbaResource );
        }
    else
        {
        TInt32 totalLength( KErrNotFound );
        TInt32 downloadedSize( KErrNotFound );

        /*
        * Get full size of media content and downloaded size
        */

        User::LeaveIfError( aDownload.GetIntAttribute
                          ( EDlAttrMultipleMOLength, totalLength ) );
        CLOG_WRITE_FORMAT(" EDlAttrMultipleMOLength: %d",totalLength);
        
        User::LeaveIfError( aDownload.GetIntAttribute
                          ( EDlAttrMultipleMODownloadedSize, downloadedSize ) );
        CLOG_WRITE_FORMAT(" EDlAttrMultipleMODownloadedSizes: %d",downloadedSize);

        HBufC8* contentType = iUiUtils.ContentTypeL( aDownload, ETrue );
        CleanupStack::PushL( contentType );

        // Don't show the confirmation query if the downloading 
        // already finished
        if ( downloadedSize == totalLength )
            {
            ret = ETrue;
            }
        else if ( 0 <= totalLength && totalLength < KDownloadConfSizeLimit )
            {
            ret = ETrue;
            }
        // GGUO-775RXR for widgets we don't need to have download confirmation either             
        else if ( contentType->Compare( KWidgetMimeType) == 0 ) 
            {
            ret = ETrue;                                
            }                                            
        else
            {
            ret = ShowDownloadConfirmationL( aDownload, aCbaResource );
            }
        CleanupStack::PopAndDestroy( contentType );            
        }

    CLOG_LEAVEFN("CUserInteractionsEventHandler::ShowDownloadConfirmationL aForce");
    return ret;
    }
// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::ShowDownloadConfirmationL
// -----------------------------------------------------------------------------
//
// Cod we used the following order
// 		name/size/type/price(optional)/description(no)/vendor(no) 

TBool CUserInteractionsEventHandler::ShowDownloadConfirmationL
    ( RHttpDownload& aDownload, TInt aCbaResource )
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::ShowDownloadConfirmationL");

    HBufC* itemText = NULL; // a buffer holding the text for each list item

    CEikFormattedCellListBox* listBox = new ( ELeave ) CAknDoublePopupMenuStyleListBox;
    CleanupStack::PushL( listBox );

    // If supported show OK & Cancel buttons, otherwise just CANCEL
    iPopupList = NULL; // reset pointer.
    CAknPopupList* popupList = CAknPopupList::NewL
            ( listBox, aCbaResource, AknPopupLayouts::EMenuDoubleWindow );
    CleanupStack::PushL( popupList );

    TInt flags = CEikListBox::EDisableHighlight;
    listBox->ConstructL( popupList, flags );
    listBox->CreateScrollBarFrameL( ETrue );
    listBox->ScrollBarFrame()->SetScrollBarVisibilityL
        ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );

    MDesCArray* itemList = listBox->Model()->ItemTextArray();
    CDesCArray* itemArray = (CDesCArray*)itemList;
    
    //-------------------------------------------
    // Header
    //
    HBufC* header = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_TITLE ); //"Download"
    popupList->SetTitleL( *header );
    CleanupStack::PopAndDestroy( header );  // header
    header = NULL;

    //-------------------------------------------
    // Check the available free space
    //
    TInt32 contentSize( 0 );
    TInt err = aDownload.GetIntAttribute( EDlAttrMultipleMOLength, contentSize );
    if ( err != KErrNone && err != KErrNotFound )
        {
        User::LeaveIfError( err );
        }

    // if size is not known it is set to -1. 0 size content size is ok here.
    TBool isContentSizeKnown = ( err == KErrNone && contentSize > -1 );

#ifdef RD_MULTIPLE_DRIVE
    if ( DiskSpaceBelowCriticalLevelL( aDownload, (TInt)contentSize ) )
#else
    if ( DiskSpaceBelowCriticalLevelL( (TInt)contentSize ) )
#endif
        {
        // Not enough free disk space!
        HBufC* notEnoughSpace = 
            StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_NOT_ENOUGH_MEM );        
        itemArray->AppendL( *notEnoughSpace );
        CleanupStack::PopAndDestroy( notEnoughSpace );  // notEnoughSpace
        // and disable OK button
        popupList->ButtonGroupContainer()->MakeCommandVisible( EAknSoftkeyOk, EFalse );
        }

    //-------------------------------------------
    // Supported?  no need - this was confirmed earlier
    //

    //-------------------------------------------
    // Add name here 
    // name/size/type/price(optional)/description(no)/vendor(no) 
   HBufC* nameHeader = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_NAME );
   HBufC* dlName = HBufC::NewLC( KMaxPath );            
   TPtr dlNamePtr = dlName->Des();
   User::LeaveIfError( aDownload.GetStringAttribute( EDlAttrName, dlNamePtr ) );

   itemText = FormatListBoxItemLC( *nameHeader, *dlName );
   itemArray->AppendL( *itemText );
   CleanupStack::PopAndDestroy( 3, nameHeader ); // itemText, sizeHeader
   dlName = NULL; 
   itemText = NULL;
   nameHeader = NULL;

    //-------------------------------------------
    // Content Size
    //
    HBufC* sizeHeader = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_SIZE );
    if ( !isContentSizeKnown )
        {
        HBufC* unknownString = StringLoader::LoadL( R_DMUL_DOWNLOADCONF_UNKNOWN );
        iSizeInfoRes.Copy( unknownString->Left(KMaxDownloadSizeTextLength) );
        delete unknownString;
        }
    else
        {
        CProgressInfoCreator* progInfoCreator = CProgressInfoCreator::NewL();
        progInfoCreator->ProgressInfo( contentSize, iSizeInfoRes );
        delete progInfoCreator;
        progInfoCreator = NULL;
        }

    itemText = FormatListBoxItemLC( *sizeHeader, iSizeInfoRes );
    itemArray->AppendL( *itemText );
    CleanupStack::PopAndDestroy( 2, sizeHeader ); // itemText, sizeHeader
    itemText = NULL;
    sizeHeader = NULL;

    //-------------------------------------------
    // Application Name - only show if Supported
    //  
    HBufC* handlerHeader = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_OPENWITH );

    RApaLsSession apaLs;
    User::LeaveIfError( apaLs.Connect() );
    CleanupClosePushL( apaLs );
    TUid appUid;
    HBufC8* contentType = iUiUtils.ContentTypeL( aDownload, ETrue );
    CleanupStack::PushL( contentType );
    
    #ifdef _DEBUG
    HBufC* contType = HBufC::NewL( contentType->Length() );
    TPtr ptr = contType->Des();
    ptr.Copy( *contentType );
    CLOG_WRITE_FORMAT(" contentType: %S",&ptr);
    delete contType;
    contType = NULL;
    #endif // _DEBUG
    
    User::LeaveIfError( apaLs.AppForDataType( TDataType(*contentType), appUid ) );
    HBufC* handlerName = ConstructHandlerAppNameLC( appUid, apaLs );

    itemText = FormatListBoxItemLC( *handlerHeader, *handlerName );
    CleanupStack::PopAndDestroy( itemText );
    
    CleanupStack::PopAndDestroy( handlerName );
    CleanupStack::Pop( contentType ); // Still needed - push later again
    CleanupStack::PopAndDestroy( &apaLs );
    CleanupStack::PopAndDestroy( handlerHeader );
    itemText = NULL;
    handlerName = NULL;
    handlerHeader = NULL;
    CleanupStack::PushL( contentType );
    
    
    //-------------------------------------------
    // MIME Content Type
    //
    HBufC* typeHeader = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_FILETYPE );

    HBufC* typeString = NULL;
    if ( contentType->Length() != 0 )
        {
        // 8 bit -> 16 bit conversion
        typeString = HBufC::NewLC( contentType->Length() );
        typeString->Des().Copy( *contentType );
        }
    else
        {       
        typeString = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_UNKNOWN );
        }

    itemText = FormatListBoxItemLC( *typeHeader, *typeString );
    itemArray->AppendL( *itemText );
    CleanupStack::PopAndDestroy( 3, typeHeader ); // itemText, typeString , typeHeader
    CleanupStack::PopAndDestroy( contentType );
    itemText = NULL;
    typeString = NULL;
    typeHeader = NULL;
    contentType = NULL;

    //-------------------------------------------
    // Price: since dm has no info, we don't need this at all here 
    //

    //-------------------------------------------
    // Description: since dm has no info, we don't need this at all here 
    //

    //-------------------------------------------
    // Vendor: since dm has no info, we don't need this at all here 
    //

    // Show popup list - it calls CActiveScheduler::Start(), so be careful 
    // when using data members after ExecuteLD!
    iDownloadConfirmationShown = ETrue;
    iPopupList = popupList;
    TBool deleted( EFalse );
    iDownloadConfirmationDeletedPtr = &deleted;
    TInt pressedOk = popupList->ExecuteLD();
    CleanupStack::Pop( popupList );    // popupList 
    if ( !deleted )
        {
        // We can use members only in this case!
        iDownloadConfirmationShown = EFalse;
        iPopupList = NULL;
        }

    // cleanup
    CleanupStack::PopAndDestroy( /*listBox*/ ); // listBox

    CLOG_WRITE_FORMAT(" pressedOk: %d",pressedOk);
    CLOG_LEAVEFN("CUserInteractionsEventHandler::ShowDownloadConfirmationL");
    return (TBool)pressedOk;
    }
    
// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::ConstructHandlerAppNameLC
// -----------------------------------------------------------------------------
//
HBufC* CUserInteractionsEventHandler::ConstructHandlerAppNameLC
    ( const TUid& aAppUid, RApaLsSession& aApaLs )
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::ConstructHandlerAppNameLC");
    
    HBufC* handlerName = NULL;
    if ( aAppUid == TUid::Null() )
        {
        // No handler found
        handlerName = StringLoader::LoadLC( R_DMUL_DOWNLOADCONF_UNKNOWN );
        }
    else
        {
        TApaAppInfo appInfo;
        User::LeaveIfError( aApaLs.GetAppInfo( appInfo, aAppUid ) );
        CLOG_WRITE_FORMAT(" appInfo.iFullName: %S",&appInfo.iFullName);
        CLOG_WRITE_FORMAT(" appInfo.iCaption: %S",&appInfo.iCaption);
        CLOG_WRITE_FORMAT(" appInfo.iShortCaption: %S",&appInfo.iShortCaption);
        // In many cases there is long caption. We should use short caption only 
        // if it is empty. They say that sometimes the long caption is not empty, 
        // but it contains only a space (0x20). In this case we must use the short.
        // For safety reasons, we will check the whole long caption, if it 
        // contains only space characters.
        const TDesC& longCap = appInfo.iCaption;
        TBool longCapIsEmpty = (longCap.Length() == 0);
        if ( longCapIsEmpty == EFalse )
            {
            TInt longCapLength = longCap.Length();
            TBool containsOnlySpaces = ETrue; // We'll change it, if it's not true.
            for (TInt i = 0; i < longCapLength; ++i)
                {
                if ( TChar(longCap[i]).IsSpace() == EFalse )
                    {
                    containsOnlySpaces = EFalse;
                    break;
                    }
                }
            if ( containsOnlySpaces )
                {
                longCapIsEmpty = ETrue;
                }
            }

        if ( longCapIsEmpty )
            {
            // Using short caption
            handlerName = appInfo.iShortCaption.AllocLC();
            }
        else
            {
            // Using long caption
            handlerName = appInfo.iCaption.AllocLC();
            }
        }
        
    CLOG_LEAVEFN("CUserInteractionsEventHandler::ConstructHandlerAppNameLC");
    return handlerName;
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::FormatListBoxItemLC
// -----------------------------------------------------------------------------
//
HBufC* CUserInteractionsEventHandler::FormatListBoxItemLC
    ( const TDesC& aFirst, const TDesC& aSecond )
    {
    HBufC* res = HBufC::NewLC( aFirst.Length() + 
                               aSecond.Length() + 
                               KListBoxSeparator().Length() );
    res->Des().Copy( aFirst );
    res->Des().Append( KListBoxSeparator );
    res->Des().Append( aSecond );
    return res;
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::HandleInProgressStateL
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::HandleInProgressStateL( TBool& aThisDeleted )
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::HandleInProgressStateL");

    // GET - download is in progress - user can cancel
    if( iEvent.iProgressState == EHttpProgCodDownloadStarted && iEvent.iDownloadState == EHttpDlInprogress )
        {
        iRegistryModel.DownloadsList().CancelDisplayingDownloadsList();                                          
        }
    if ( iEvent.iProgressState == EHttpContTypeRecognitionAvail )
        {
        // Don't show confirmation query for COD downloads
        TBool isCodDownload( EFalse );
		TBool userConfirms( EFalse );
        User::LeaveIfError( iDownload.GetBoolAttribute
                          ( EDlAttrCodDownload, isCodDownload ) );
        if ( isCodDownload )
            {
            // Do nothing.
            }
        else
            {
            // Check if multipart
            HBufC8* contentType = HBufC8::NewLC( KMaxContentTypeLength );
            TPtr8 contentTypePtr = contentType->Des();
            User::LeaveIfError
                ( iDownload.GetStringAttribute( EDlAttrContentType, contentTypePtr ) );
            if( 0 == contentType->Compare( KMultiPartMimeType ) )
                {
                // Don't show confirmation query yet, but 
                // observe EHttpProgSupportedMultiPart.
                }
            else
                {
                iUiUtils.IsContentTypeSupportedL( iDownload );
                TBool suppressDownloadConfirmation( EFalse );
                iRegistryModel.UserInteractions().GetBoolAttributeL
                    ( CDownloadMgrUiUserInteractions::EAttrSuppressDownloadConfirmation, 
                      suppressDownloadConfirmation );
                CLOG_WRITE_FORMAT(" suppressDownloadConfirmation: %d", 
                                    suppressDownloadConfirmation);

                if ( suppressDownloadConfirmation )
                    {
                    // Nothing to do.
                    }
                else
                    {
                    TInt32 statusCode(0);
                    User::LeaveIfError( iDownload.GetIntAttribute
                                      ( EDlAttrStatusCode, statusCode ) );
                    if ( statusCode == 206 ) // http status code
                        {
                        // Display information note (only if the DL is not visible)
                        if ( iRegistryModel.DownloadsListInstalled() )
                            {
                            if ( !iRegistryModel.DownloadsList().IsVisible() )
                                {
                                CUserInteractionsUtils::InfoNoteL
                                    ( R_DMUL_OK_NOTE, R_DMUL_NOTE_DOWNLOADING );
                                }
                            }
                        }
                    else
                        {
                        userConfirms = ShowDownloadConfirmationL
                            ( iDownload, R_AVKON_SOFTKEYS_OK_CANCEL__OK, EFalse );
                                             
                        // executes a wait dialog! Check if this is deleted meanwhile
                        if ( aThisDeleted )
                            {
                            CLOG_WRITE_FORMAT(" this deleted: %x", this);
                            CLOG_LEAVEFN("CUserInteractionsEventHandler::HandleInProgressStateL");
                            CleanupStack::PopAndDestroy( contentType );
                            return;
                            }
                            
                        if ( userConfirms )
                            {
                            TBool isLaunchType( EFalse );
                            if( iUiUtils.DrmDownloadL( iDownload ) )
                                {
                                // get content type of media file in drm content
                                HBufC8* ctype = iUiUtils.ContentTypeL( iDownload, ETrue );
                                if( KDrmInnerContentTypesToLaunch().Find( *ctype )
                                    != KErrNotFound )
                                    {
                                    isLaunchType = ETrue;
                                    }
                                delete ctype;
                                }
                            if( isLaunchType )
                                {
                                User::LeaveIfError( iDownload.SetIntAttribute(
                                    EDlAttrAction, ELaunch ) );
                                }
                            else
                                {
                                //part of error PNIO-73GEM3.Sis file progress should be visible to user
                                if( (KSisxApplication().Find( contentTypePtr)!= KErrNotFound) || 
                                    (KPipApplication().Find( contentTypePtr)!= KErrNotFound) ||
                                    (KWidgetMimeType().Find( contentTypePtr)!= KErrNotFound) ||
                                    (KSharingConfig().Find( contentTypePtr)!= KErrNotFound) )
                                    {
                                    isLaunchType = ETrue;
                                    User::LeaveIfError( iDownload.SetIntAttribute(
                                        EDlAttrAction, ELaunch ) );                                    
                                    }
                                // Open the download list if there is no more 
                                // download confirmation shown:
                                if ( iRegistryModel.UserInteractions().
                                    DownloadConfirmationsShown() == 0 )
                                    {
                                    if ( iRegistryModel.DownloadsListInstalled() )
                                        {
                                        iRegistryModel.DownloadsList().
                                            DisplayDownloadsListL( iDownload );
                                        }
                                    }
                                }
                            }
                        else
                            {
                            // The download must be removed from Downloads List
                            User::LeaveIfError( iDownload.Delete() );
                            CLOG_WRITE(" Delete OK");
                            }
                        }
                     }
                    if (userConfirms)
					{
                   
	#ifdef __DMGR_PD_TESTHARNESS
                        iUiUtils.TestLaunchPdAppL(iDownload);
	#else	           
 		//#ifdef RD_BROWSER_PROGRESSIVE_DOWNLOAD	               

                        // check if it's PdLaunch action 
		                TInt32 action(0);
                        User::LeaveIfError( iDownload.GetIntAttribute( EDlAttrAction, action ) );                    
                        if( (action & EPdLaunch) && 
                            iUiUtils.CanLaunchAsProgDownload( iDownload, iRegistryModel.DownloadsList(),EFalse ))
                            {
      						CLOG_WRITE( " launchPdAppL(iDownload)" );
						    iUiUtils.LaunchPdAppL(iDownload, ETrue);
						    }
		//#endif	//RD_BROWSER_PROGRESSIVE_DOWNLOAD
	#endif	//__DMGR_PD_TESTHARNESS	
					}
                }
            CleanupStack::PopAndDestroy( contentType ); // contentType
            }
        }
    else if ( iEvent.iProgressState == EHttpProgCodPdAvailable )
        {
        TBool isCodPdAvailable( EFalse );
        User::LeaveIfError( iDownload.GetBoolAttribute
                          ( EDlAttrCodPdAvailable, isCodPdAvailable ) );
        if ( isCodPdAvailable )
            {
			
			#ifdef __DMGR_PD_TESTHARNESS
				iUiUtils.TestLaunchPdAppL(iDownload);
			#else
	            // check if it's PdLaunch action 
	            TInt32 action(0);
                User::LeaveIfError( iDownload.GetIntAttribute( EDlAttrAction, action ) );                    
				if ( (action & EPdLaunch) && 
                    iUiUtils.CanLaunchAsProgDownload( iDownload, iRegistryModel.DownloadsList(),ETrue ))
					{
					iUiUtils.LaunchPdAppL(iDownload, ETrue);
					}
			#endif	//__DMGR_PD_TESTHARNESS
			}
        }        
    else if ( iEvent.iProgressState == EHttpProgCodDescriptorAccepted )
        {
        // COD load accepted. Download is turned to visible, and 
        // downloads list is shown.
        User::LeaveIfError( iDownload.SetBoolAttribute
                          ( EDlAttrHidden, EFalse ) );
        CLOG_WRITE(" SetBoolAttribute EDlAttrHidden OK");
        // If this download's ServiceFlow was running, it's not more 
        // a ServiceFlow, thus the next postponed download can be 
        // scheduled.
        if ( iRegistryModel.UserInteractions().IsCodServiceFlowRunning( iDownload ) )
            {
            iRegistryModel.UserInteractions().SchedulePostponedDownloadL();
            }
        // Display downloads list
        if ( iRegistryModel.DownloadsListInstalled() )
            {
            iRegistryModel.DownloadsList().
                DisplayDownloadsListL( iDownload );
            }
        }
    else if ( iEvent.iProgressState == EHttpProgCodLoadEnd )
        {
        // UI state must be checked before we set download to hidden!
        TBool isUiBusyNow = iRegistryModel.UserInteractions().IsUiBusy();
        // COD load has ended. Download is turned to hidden, removed from 
        // downloads list, and restarted (ServiceFlow).
        CLOG_WRITE(" SetBoolAttribute EDlAttrHidden OK");

        // Restart if possible - start ServiceFlow.
        // (UserInteractions must be installed...)
        if ( isUiBusyNow )
            {
            // Not possible to do it. Postpone the Service Flow and 
            // invoke when no more handler is running.
            // The download is already hidden!
            iRegistryModel.UserInteractions().PostponeCodHandlingL( iDownload );
             //Download will be handled when the UI becomes free.
            }
        else
            {
            CLOG_WRITE(" (Re)Starting...");
            User::LeaveIfError( iDownload.Start() );
            CLOG_WRITE(" (Re)Start OK");
            }
        }
    else if ( iEvent.iProgressState == EHttpProgSupportedMultiPart )
        {
        // Show download confirmation for multipart download, if appropriate.
        // Don't show confirmation query for COD downloads
        TBool isCodDownload( EFalse );
        User::LeaveIfError( iDownload.GetBoolAttribute
                          ( EDlAttrCodDownload, isCodDownload ) );
        if ( isCodDownload )
            {
            // Do nothing.
            }
        else
            {
            TBool suppressDownloadConfirmation( EFalse );
            iRegistryModel.UserInteractions().GetBoolAttributeL
                ( CDownloadMgrUiUserInteractions::EAttrSuppressDownloadConfirmation, 
                  suppressDownloadConfirmation );
            CLOG_WRITE_FORMAT(" suppressDownloadConfirmation: %d", 
                                suppressDownloadConfirmation);

            if ( suppressDownloadConfirmation )
                {
                // Nothing to do.
                }
            else
                {
                TBool userConfirms = ShowDownloadConfirmationL
                    ( iDownload, R_AVKON_SOFTKEYS_OK_CANCEL__OK, EFalse );
                                     
                // executes a wait dialog! Check if this is deleted meanwhile
                if ( aThisDeleted )
                    {
                    CLOG_WRITE_FORMAT(" this deleted: %x", this);
                    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandleInProgressStateL");
                    return;
                    }
                    
                if ( userConfirms )
                    {
                    // Open the download list if there is no more 
                    // download confirmation shown:
                    if ( iRegistryModel.UserInteractions().
                                        DownloadConfirmationsShown() == 0 )
                        {
                        if ( iRegistryModel.DownloadsListInstalled() )
                            {
                            iRegistryModel.DownloadsList().
                                DisplayDownloadsListL( iDownload );
                            }
                        }
                    }
                else
                    {
                    // The download must be removed from Downloads List
                    User::LeaveIfError( iDownload.Delete() );
                    CLOG_WRITE(" Delete OK");
                    }
                }
            }
        }

    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandleInProgressStateL");
    }

    
// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::HandlePausedStateL
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::HandlePausedStateL( TBool& aThisDeleted )
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::HandlePausedStateL");

    // HEAD - download is paused - started if user confirms
    if ( iEvent.iProgressState == EHttpContentTypeReceived )
        {
        // Don't show confirmation query for COD downloads
        TBool isCodDownload( EFalse );
        User::LeaveIfError( iDownload.GetBoolAttribute
                          ( EDlAttrCodDownload, isCodDownload ) );
        if ( isCodDownload )
            {
            // COD downloads cannot be paused!
            }
        else
            {
            TBool suppressDownloadConfirmation( EFalse );
            iRegistryModel.UserInteractions().GetBoolAttributeL
                ( CDownloadMgrUiUserInteractions::EAttrSuppressDownloadConfirmation, 
                  suppressDownloadConfirmation );
            CLOG_WRITE_FORMAT(" suppressDownloadConfirmation: %d", 
                                suppressDownloadConfirmation);

            if ( suppressDownloadConfirmation )
                {
                // Nothing to do, just resume the download.
                User::LeaveIfError( iDownload.Start() );
                CLOG_WRITE(" Restart OK");
                }
            else
                {
                aThisDeleted = EFalse;
                TBool userConfirms = ShowDownloadConfirmationL
                                     ( iDownload, R_AVKON_SOFTKEYS_OK_CANCEL__OK, EFalse );

                // executes a wait dialog! Check if this is deleted meanwhile
                if ( aThisDeleted )
                    {
                    CLOG_WRITE_FORMAT(" this deleted: %x", this);
                    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandlePausedStateL");
                    return;
                    }
                    
                // Open Downloads List if user confirms:
                if ( userConfirms )
                    {
                    // Resume the download:
                    User::LeaveIfError( iDownload.Start() );
                    // and open the download list if there is no more 
                    // download confirmation shown:
                    if ( iRegistryModel.UserInteractions().
                                        DownloadConfirmationsShown() == 0 )
                        {
                        if ( iRegistryModel.DownloadsListInstalled() )
                            {
                            iRegistryModel.DownloadsList().
                                DisplayDownloadsListL( iDownload );
                            }
                        }
                    }
                else
                    {
                    // The download must be removed from Downloads List
                    User::LeaveIfError( iDownload.Delete() );
                    CLOG_WRITE(" Delete OK");
                    }
                }
            }
        }

    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandlePausedStateL");
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::HandleCompletedStateL
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::HandleCompletedStateL()
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::HandleCompletedStateL");

    if ( iEvent.iProgressState == EHttpProgMovingContentFile )
        {
        // An asynchronous move has started. Do nothing.
        CLOG_WRITE(" Move has started");
        }
    else if ( iEvent.iProgressState == EHttpProgContentFileMoved || iEvent.iProgressState == EHttpProgContentFileMovedAndDestFNChanged )
        {
        // An asynchronous move has ended.
        
        CLOG_WRITE(" Move has ended");
        // After successful moving, display updated download list
        iRegistryModel.DownloadsList().DisplayDownloadsListL( iDownload );
        // Notify Media Gallery about new media file
        // first get path to gallery where file was moved
        HBufC* fileName = HBufC::NewLC( KMaxPath );
        TPtr fileNamePtr = fileName->Des();
        TInt attErr = iDownload.GetStringAttribute( 
            EDlAttrDestFilename, fileNamePtr );
        CLOG_WRITE_FORMAT(" EDlAttrDestFilename: %S",&fileNamePtr);
        TBool havePath = (attErr == KErrNone) && (fileNamePtr.Length() > 0);
        
        #ifdef BRDO_APP_GALLERY_SUPPORTED_FF
        //
        CMGXFileManager* mgFileManager = MGXFileManagerFactory::NewFileManagerL(
            CEikonEnv::Static()->FsSession() );
        if( havePath )
            {
            TRAP_IGNORE( mgFileManager->UpdateL( fileNamePtr ) );
            TRAP_IGNORE( iUiUtils.UpdateDCFRepositoryL( fileNamePtr ) );
            }
        else
            {
            TRAP_IGNORE( mgFileManager->UpdateL() );
            }
        
        delete mgFileManager;
        mgFileManager = NULL;
        
        #else
         if( havePath )
            {
            TRAP_IGNORE( iUiUtils.UpdateDCFRepositoryL( fileNamePtr ) );
            }
        #endif    
        
        CleanupStack::PopAndDestroy( fileName );
        
        }
    else
        {
        // Normal completed state. Handling depends on EDlAttrAction
        TInt32 action(0);
        User::LeaveIfError( iDownload.GetIntAttribute
                            ( EDlAttrAction, action ) );
        CLOG_WRITE_FORMAT(" EDlAttrAction: %d",action);
        if ( action == EDoNothing )
            {
            // Do nothing
            }
        else if ( action & EMove )
            {
            // check if COD download
            TBool isCodDownload( EFalse );
            User::LeaveIfError( iDownload.GetBoolAttribute
                              ( EDlAttrCodDownload, isCodDownload ) );

            // check if progressive download
            TBool isProgressive = EFalse;
            TInt err = iDownload.GetBoolAttribute
                ( EDlAttrProgressive, isProgressive );
            CLOG_WRITE_FORMAT(" EDlAttrProgressive err: %d",err);
            // 'err' is ignored.
            CLOG_WRITE_FORMAT(" EDlAttrProgressive: %d", isProgressive);
            
            // check if move is already issued
            TBool isMoveIssued = EFalse;
            TInt32 progState(0);
            User::LeaveIfError( iDownload.GetIntAttribute
                            ( EDlAttrProgressState, progState ) );
            
            if(progState == EHttpProgMovingContentFile) isMoveIssued = ETrue;    

            if( isCodDownload )
                {
                HBufC8* contentType = HBufC8::NewLC( KMaxContentTypeLength );
                TPtr8 contentTypePtr = contentType->Des();
                User::LeaveIfError
                    ( iDownload.GetStringAttribute( EDlAttrContentType, contentTypePtr ) ); 
                if( !contentType->Compare(KRoapMimeType))
                    {
                    User::LeaveIfError
                    ( iDownload.Delete());
                    }
                CleanupStack::PopAndDestroy( contentType );    
                }
             else if( isProgressive || isMoveIssued )
                {
                //do not move
                
                }
             else
                {
                // Move content to the location defined by KDownloadPath

                // first, get current EDlAttrDestFilename
			    HBufC* fileName = HBufC::NewLC( KMaxPath );
			    TPtr fileNamePtr = fileName->Des();
			    User::LeaveIfError
                    ( iDownload.GetStringAttribute( EDlAttrDestFilename, fileNamePtr ) );

                RFs& fs = CEikonEnv::Static()->FsSession();

#ifdef RD_MULTIPLE_DRIVE
                TDriveUnit currentDrive(fileNamePtr);

                // using PathInfo::RootPath to set correct destination folder
                // depending on memory used

                // Getting RootPath for selected Drive
                TFileName rootPath;
                User::LeaveIfError( PathInfo::GetRootPath( rootPath, currentDrive ) );

                // remove path from EDlAttrDestFilename
                if( fileNamePtr.Length() > 0 )
                    {
                    TInt lastSlashPos = fileNamePtr.LocateReverse( '\\' );
                    if( lastSlashPos != KErrNotFound )
                        {
                        fileNamePtr.Delete( 0, lastSlashPos );
                        }
                    }
            
                // Setting RootPath for new Destination file
                fileNamePtr.Insert( 0, rootPath );
                // Setting KDownloadPath
                fileNamePtr.Insert( rootPath.Length(), KDownloadPath );
#else
                
                TParse p;
                p.SetNoWild(fileNamePtr, NULL, NULL);
                TDriveUnit currentDrive(fileNamePtr);
                TFileName rootPath;
                User::LeaveIfError( PathInfo::GetRootPath( rootPath, currentDrive ) );
                
                TPtrC namePtr = p.NameAndExt();
                fileNamePtr.Format( _L("%S%S\\%S"), &rootPath,
                                                    &KDownloadPath,
                                                    &namePtr );
#endif
                // next, creating directory
                TInt error = 0;

                // next, get the directory path from new EDlAttrDestFilename
                if( fileNamePtr.Length() > 0 )
                    {
                    TInt lastSlashPos = fileNamePtr.LocateReverse( '\\' );
                    if( lastSlashPos != KErrNotFound )
                        {
                        error = fs.MkDirAll( fileNamePtr.LeftTPtr( lastSlashPos + 1 ) );
                        if ( error != KErrNone && error != KErrAlreadyExists )
                            // leave if makedir failed in some way
                            // don't leave if already exists
                            {
                            CLOG_WRITE_FORMAT( "MkDirAll: %d", error );
                            User::Leave( error );
                            }
                        }
                    }


                // update EDlAttrDestFilename with new path
                User::LeaveIfError
		                ( iDownload.SetStringAttribute( EDlAttrDestFilename, *fileName ) );
                // move file
                User::LeaveIfError( iDownload.Move() );
          	    CleanupStack::PopAndDestroy( fileName ); // fileName
                }
            }
        else if ( action & EPdLaunch )
        {
        	// do nothing since PdLaunch was already launched during the progress 
        }
        else
            {
            // Defaulting to Launch
            iRegistryModel.UserInteractions().HandleDownloadL( iDownload );
            }
        }

    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandleCompletedStateL");

    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::HandleFailedStateL
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::HandleFailedStateL()
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::HandleFailedStateL");

    // check if it is COD download
    TBool isCodDownload( EFalse );
    User::LeaveIfError( iDownload.GetBoolAttribute
                      ( EDlAttrCodDownload, isCodDownload ) );
    CLOG_WRITE_FORMAT("EDlAttrCodDownload: %d",isCodDownload);
    if ( isCodDownload )
        {
        // If the ServiceFlow of the download was running, but failed, 
        // schedule the next download for running. 
        // UserInteractions is assumed to be installed.
        // Do not delete the download yet (because IsCodServiceFlowRunning needs it)!
        if ( iRegistryModel.UserInteractions().IsCodServiceFlowRunning( iDownload ) )
            {
            iRegistryModel.UserInteractions().SchedulePostponedDownloadL();
            }
        // Nothing to do with COD - just delete it.
        HandleUnrecoverableFailL();
        }
    else // NORMAL download
        {
        // What is the error?
        TInt32 errorId( KErrNone ); // DMgr specific error ID
        User::LeaveIfError( iDownload.GetIntAttribute( EDlAttrErrorId, errorId ) );
        CLOG_WRITE_FORMAT(" Fail reason: %d", errorId);
        //
        if ( errorId == EHttpAuthenticationFailed )
            {
            if ( iUiUtils.GetAndSetHttpAuthCredentialsL( iDownload ) )
                {
                // and continue download
                User::LeaveIfError( iDownload.Start() );
                }
            }
        else if ( errorId == EProxyAuthenticationFailed )
            {
            if ( iUiUtils.GetAndSetProxyAuthCredentialsL( iDownload ) )
                {
                // and continue download
                User::LeaveIfError( iDownload.Start() );
                }
            }
        else if ( errorId == EHttpRestartFailed )
            {
            // Do not handle it.
            }
        else
            {
            TBool errorHandled( EFalse );
            
            if ( !errorHandled )
                {
                iUiUtils.ShowErrorNoteL( iDownload, errorId );
                // This component is responsible for deleting 
                // not recoverable downloads
                if ( iUiUtils.IsRecoverableFailL( iDownload, errorId ) )
                    {
                    // Do nothing.
                    }
                else
                    {
                    // Delete the download
                    HandleUnrecoverableFailL();
                    }
                }
            }
        }

    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandleFailedStateL");
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::HandleUnrecoverableFailL
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::HandleUnrecoverableFailL()
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::HandleUnrecoverableFailL");

    HBufC* dlName = HBufC::NewLC( KMaxPath );
    TPtr dlNamePtr = dlName->Des();
    User::LeaveIfError( iDownload.GetStringAttribute( EDlAttrName, dlNamePtr ) );
    CLOG_WRITE_FORMAT(" EDlAttrName: %S",&dlNamePtr);

    // If download name is empty, use the file name got from URI
    if ( dlName->Length() == 0 )
        {
        HBufC* url = HBufC::NewLC( KMaxUrlLength );
        TPtr urlPtr = url->Des();
        TInt err = iDownload.GetStringAttribute( EDlAttrCurrentUrl, urlPtr );
        CLOG_WRITE_FORMAT(" EDlAttrCurrentUrl err: %d",err);
        if ( err != KErrNone && err != KErrNotFound )
            {
            User::LeaveIfError( err );
            }
        CLOG_WRITE_FORMAT(" EDlAttrCurrentUrl: %S",url);
        if ( url->Length() > 0 )
            {
            // Extract file name, if possible
            CUri8* converted = UriUtils::CreateUriL( *url );
            CleanupStack::PushL( converted );
            HBufC* extracted = converted->Uri().GetFileNameL( EUriFileNameTail );
            CleanupStack::PushL( extracted );
            // Use this for download name
            // (Left() is used to avoid overflow.)
            dlNamePtr.Copy( extracted->Left( dlNamePtr.MaxLength() ) );
            CleanupStack::PopAndDestroy( extracted );
            CleanupStack::PopAndDestroy( converted );
            }
        CleanupStack::PopAndDestroy( url );
        }

    // iDownload can now been deleted        
    User::LeaveIfError( iDownload.Delete() );
    CLOG_WRITE(" Delete OK");

    HBufC* infoPrompt = StringLoader::LoadLC( R_DMUL_ERROR_CANCELLED, *dlName );
    CLOG_WRITE(" StringLoader OK");
    
    CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog();
    dlg->PrepareLC( R_DMUL_DOWNLOAD_OK_INFO );
    dlg->SetTextL( *infoPrompt );
    dlg->RunLD();
    CLOG_WRITE(" RunLD OK");

    CleanupStack::PopAndDestroy( infoPrompt );
    CleanupStack::PopAndDestroy( dlName );

    CLOG_LEAVEFN("CUserInteractionsEventHandler::HandleUnrecoverableFailL");
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::DoCancel
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::DoCancel()
    {
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::RunL
// -----------------------------------------------------------------------------
//
void CUserInteractionsEventHandler::RunL()
    {
    CLOG_ENTERFN("CUserInteractionsEventHandler::RunL");
    CLOG_WRITE_FORMAT(" %x", this);
    CLOG_WRITE_EVENT("UsrIntEve",&iDownload,iEvent);

    // This RunL may show wait dialogs. Use an indicator for if this is deleted
    TBool deleted( EFalse );
    iDeletedPtr = &deleted;

    // Incase of completed and moved downloads, subsession will be closed and whole download info will be cached client side. 
    // No need to check for subsession close    
    if(!(iEvent.iDownloadState == EHttpDlMultipleMOCompleted && (iEvent.iProgressState == EHttpProgContentFileMoved || iEvent.iProgressState == EHttpProgContentFileMovedAndDestFNChanged )))
        {
        // Due to the postponed event handling, it may happen that somebody already 
        // closed the download meanwhile. Check if it is still alive:
        if ( iDownload.SubSessionHandle() == 0 )
            {
            // No, it's already closed!! Do nothing.
            // Necessary task done in RunL. This object is no more necessary.
            CLOG_WRITE(" Zero handle!");
            delete this;
            CLOG_LEAVEFN("CUserInteractionsEventHandler::RunL");
            return;
            }
        }
    
    switch ( iEvent.iDownloadState )
        {
        //---------------------------------------------
        case EHttpDlCreated:
        //---------------------------------------------
            {
            break;
            }
        //---------------------------------------------
        case EHttpDlInprogress:
        //---------------------------------------------
            {
            HandleInProgressStateL( deleted );
            break;
            }
        //---------------------------------------------
        case EHttpDlPaused:
        //---------------------------------------------
            {
            HandlePausedStateL( deleted );
            break;
            }
        //---------------------------------------------
        case EHttpDlMultipleMOCompleted:
        //---------------------------------------------
            {
            HandleCompletedStateL();
            break;
            }
        //---------------------------------------------
        case EHttpDlMultipleMOFailed:
        //---------------------------------------------
            {
            HandleFailedStateL();
            break;
            }
        //---------------------------------------------
        case EHttpDlMoved:
        //---------------------------------------------
            {
            // Do nothing. Downloads List handles it.
            break;
            }
        //---------------------------------------------
        case EHttpDlMediaRemoved:
        //---------------------------------------------
            {
            iUiUtils.ShowMediaRemovedNoteL();
            break;
            }
        //---------------------------------------------
        default:
        //---------------------------------------------
            {
            break;
            }
        }

    CLOG_WRITE_FORMAT(" deleted: %d",deleted);
    if ( !deleted )
        {
        // Necessary task done in RunL. This object is no more necessary.
        delete this;
        }
    
    CLOG_LEAVEFN("CUserInteractionsEventHandler::RunL");
    }

// -----------------------------------------------------------------------------
// CUserInteractionsEventHandler::RunError
// -----------------------------------------------------------------------------
//
TInt CUserInteractionsEventHandler::RunError( TInt aError )
    {
    if ( aError )
        {
        TRAP_IGNORE( iUiUtils.ShowErrorNoteL( aError ) );
        }
    return KErrNone;
    }

// End of file.
