harvester/common/src/harvesterpluginfactory.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 15:02:02 +0300
branchRCL_3
changeset 63 e538444823de
parent 53 29d87345eaeb
permissions -rw-r--r--
Revision: 201039 Kit: 201041

/*
* Copyright (c) 2006-2009 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:  Harvester plugin factory
 *
*/


#include <e32base.h>
#include <e32std.h>
#include <apmrec.h>
#include <harvesterplugin.h>
#include <mdeobject.h>
#include <harvesterdata.h>
#include "harvestereventmanager.h"
#include "harvesterpluginfactory.h"
#include "harvesterplugininfo.h"
#include "mdsutils.h"
#include "harvesterlog.h"

// for CleanupResetAndDestroyPushL
#include <mmf/common/mmfcontrollerpluginresolver.h>

const TInt KCacheItemCountForEventCaching = 1;

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CHarvesterPluginFactory::CHarvesterPluginFactory() :
    iBlacklist( NULL ),
    iHarvesting( EFalse ),
    iHarvesterEventManager( NULL )
	{
	WRITELOG( "CHarvesterPluginFactory::CHarvesterPluginFactory()" );
	}

// ---------------------------------------------------------------------------
// NewL
// ---------------------------------------------------------------------------
//
EXPORT_C CHarvesterPluginFactory* CHarvesterPluginFactory::NewL()
	{
	WRITELOG( "CHarvesterPluginFactory::NewL()" );
	CHarvesterPluginFactory* self = new (ELeave) CHarvesterPluginFactory();
	CleanupStack::PushL ( self);
	self->ConstructL ();
	CleanupStack::Pop ( self);

	return self;
	}

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CHarvesterPluginFactory::~CHarvesterPluginFactory()
	{
	WRITELOG( "CHarvesterPluginFactory::~CHarvesterPluginFactory()" );
	
    if (iHarvesterEventManager)
        {
        iHarvesterEventManager->ReleaseInstance();
        }
	
	iHarvesterPluginInfoArray.ResetAndDestroy();
	iHarvesterPluginInfoArray.Close();
	REComSession::FinalClose();
	}

// ---------------------------------------------------------------------------
// ConstructL
// ---------------------------------------------------------------------------
//
void CHarvesterPluginFactory::ConstructL()
	{
	WRITELOG( "CHarvesterPluginFactory::ConstructL()" );
	iHarvesterEventManager = CHarvesterEventManager::GetInstanceL();
	SetupHarvesterPluginInfoL();
	}

// ---------------------------------------------------------------------------
// GetObjectDef
// ---------------------------------------------------------------------------
//
EXPORT_C void CHarvesterPluginFactory::GetObjectDefL( CHarvesterData& aHD, TDes& aObjectDef )
	{
	TPtrC extPtr;
	if( MdsUtils::GetExt( aHD.Uri(), extPtr ) )
		{
		RPointerArray<CHarvesterPluginInfo> supportedPlugins;
		CleanupClosePushL( supportedPlugins );
		GetSupportedPluginsL( supportedPlugins, extPtr );
		
		const TInt sCount = supportedPlugins.Count();
		if( sCount == 1 )
			{
			CHarvesterPluginInfo* info = supportedPlugins[0];
			if( info->iObjectTypes.Count() == 1 )
				{
				aObjectDef.Copy( *(info->iObjectTypes[0]) );
				aHD.SetHarvesterPluginInfo( info );
				CleanupStack::PopAndDestroy( &supportedPlugins );
				return;
				}
			}
		for( TInt i = sCount - 1; i >=0; i-- )
			{
			CHarvesterPluginInfo* info = supportedPlugins[i];
			if ( !(info->iPlugin) )
				{
				info->iPlugin = CHarvesterPlugin::NewL( info->iPluginUid );
				info->iPlugin->SetQueue( info->iQueue );
				info->iPlugin->SetHarvesterPluginFactory( *this );  
				info->iPlugin->SetBlacklist( *iBlacklist );
				}
			info->iPlugin->GetObjectType( aHD.Uri(), aObjectDef );
			if( aObjectDef.Length() > 0 )
				{
				aHD.SetHarvesterPluginInfo( info );
				break;
				}
			}
		CleanupStack::PopAndDestroy( &supportedPlugins );
		}
	else
		{
		aObjectDef.Zero();
		}
	}
	
// ---------------------------------------------------------------------------
// GetMimeType
// ---------------------------------------------------------------------------
//
EXPORT_C void CHarvesterPluginFactory::GetMimeType(const TDesC& aUri, TDes& aMimeType)
	{
    TPtrC extPtr;
    if( MdsUtils::GetExt( aUri, extPtr ) )
        {
        RPointerArray<CHarvesterPluginInfo> supportedPlugins;
        TRAP_IGNORE( GetSupportedPluginsL( supportedPlugins, extPtr ) );
        
        for( TInt i = supportedPlugins.Count() - 1; i >=0; i-- )
            {
            CHarvesterPluginInfo* info = supportedPlugins[i];
            if ( !(info->iPlugin) )
                {
                TRAPD( error, info->iPlugin = CHarvesterPlugin::NewL( info->iPluginUid ) );
                if( error != KErrNone )
                    {
                    aMimeType.Zero();
                    return;
                    }
                info->iPlugin->SetQueue( info->iQueue );
                info->iPlugin->SetHarvesterPluginFactory( *this );  
                info->iPlugin->SetBlacklist( *iBlacklist );
                }
            info->iPlugin->GetMimeType( aUri, aMimeType );
            if( aMimeType.Length() > 0 )
                {
                break;
                }
            }
        supportedPlugins.Close();
        }
    else
        {
        aMimeType.Zero();
        }
	}

// ---------------------------------------------------------------------------
// HarvestL
// ---------------------------------------------------------------------------
//
EXPORT_C TInt CHarvesterPluginFactory::HarvestL( CHarvesterData* aHD )
	{
#ifdef _DEBUG
	WRITELOG1("CHarvesterPluginFactory::HarvestL - aHD->Uri: %S", &aHD->Uri() );
#endif
	CHarvesterPluginInfo* hpi = aHD->HarvesterPluginInfo();
	
	if( !hpi )
	    {
	    SetPluginInfo( aHD );
	    hpi = aHD->HarvesterPluginInfo();
	    }
	
	if ( hpi )
		{
		if ( ! hpi->iPlugin )
	   		{
	   		hpi->iPlugin = CHarvesterPlugin::NewL( hpi->iPluginUid );
	   		hpi->iPlugin->SetQueue( hpi->iQueue );
	   		hpi->iPlugin->SetHarvesterPluginFactory( *this );  
	   		hpi->iPlugin->SetBlacklist( *iBlacklist );
	   		}
			
		if( aHD->ObjectType() == EFastHarvest || aHD->Origin() == MdeConstants::Object::ECamera )
		   	{
		   	hpi->iQueue.Insert( aHD, 0 );
		   	if( !hpi->iPlugin->IsActive() )
		   	    {
	            hpi->iPlugin->SetPriority( KHarvesterPriorityHarvestingPlugin + 1 );
		   	    }
		    }
	    else
			{
			hpi->iQueue.AppendL( aHD );
			}
		    
		hpi->iPlugin->StartHarvest();
			
		return KErrNone;
		}
		
	return KErrNotFound;
	}

// ---------------------------------------------------------------------------
// GetPluginInfos
// ---------------------------------------------------------------------------
//
EXPORT_C RPointerArray<CHarvesterPluginInfo>& CHarvesterPluginFactory::GetPluginInfos()
	{
	return iHarvesterPluginInfoArray;
	}

// ---------------------------------------------------------------------------
// SetBlacklist
// ---------------------------------------------------------------------------
//
EXPORT_C void CHarvesterPluginFactory::SetBlacklist( CHarvesterBlacklist& aBlacklist )
	{
	WRITELOG( "CHarvesterPluginFactory::SetBlacklist()" );
	iBlacklist = &aBlacklist;
	
	const TInt count = iHarvesterPluginInfoArray.Count();
	for ( TInt i = count; --i >= 0; )
		{
	    if( iHarvesterPluginInfoArray[i]->iPlugin )
	        {
	        iHarvesterPluginInfoArray[i]->iPlugin->SetBlacklist( *iBlacklist );
	        }
		}	
	}

// ---------------------------------------------------------------------------
// SetupHarvesterPluginInfoL
// ---------------------------------------------------------------------------
//
void CHarvesterPluginFactory::SetupHarvesterPluginInfoL()
    {
    WRITELOG( "CHarvesterPluginFactory::SetupHarvesterPluginInfo()" );
    
    RImplInfoPtrArray infoArray;
    TCleanupItem cleanupItem( MdsUtils::CleanupEComArray, &infoArray );
    CleanupStack::PushL( cleanupItem );
 
    CHarvesterPlugin::ListImplementationsL( infoArray );

    for ( TInt i = infoArray.Count(); --i >= 0; )
        {
        // Parse the MIME types and resolve plug-in's uids from infoArray to iDataTypeArray
        CImplementationInformation* info = infoArray[i];
        const TBufC8<KMaxFileName>& type = info->DataType();
        const TBufC8<KMaxFileName>& opaque = info->OpaqueData();
        TUid implUID = info->ImplementationUid(); 
                
        AddNewPluginL( type, opaque, implUID );   
        }
    
    CleanupStack::PopAndDestroy( &infoArray );
    }

// ---------------------------------------------------------------------------
// AddNewPluginL
// ---------------------------------------------------------------------------
//
void CHarvesterPluginFactory::AddNewPluginL( const TDesC8& aType,
		const TDesC8& aOpaque, TUid aPluginUid )
    {      
    WRITELOG( "CHarvesterPluginFactory::AddNewPluginL" );

    CHarvesterPluginInfo* pluginInfo = new (ELeave) CHarvesterPluginInfo;
    CleanupStack::PushL( pluginInfo );

    // get file extensions
    TLex8 lex( aOpaque );
    while ( !lex.Eos() )
        {
        /* Tokenizing file extensions using TLex8 */
        lex.SkipSpaceAndMark();

        TPtrC8 extToken = lex.NextToken();

        HBufC* str = HBufC::NewLC( extToken.Length() );
        str->Des().Copy( extToken );
        pluginInfo->iExtensions.AppendL( str );
        CleanupStack::Pop( str );
        }

    // get object types
    TLex8 lexObjectTypes( aType );
    while ( !lexObjectTypes.Eos() )
        {
        /* Tokenizing object types using TLex8 */
        lexObjectTypes.SkipSpaceAndMark();
        
        TPtrC8 objectTypeToken = lexObjectTypes.NextToken();

        HBufC* str = HBufC::NewLC( objectTypeToken.Length() );
        str->Des().Copy( objectTypeToken );
        pluginInfo->iObjectTypes.AppendL( str );
        CleanupStack::Pop( str );
        }
    
    pluginInfo->iPluginUid = aPluginUid;
    
#ifdef MDS_HARVESTERPLUGINS_ON_BOOT
    pluginInfo->iPlugin = CHarvesterPlugin::NewL( pluginInfo->iPluginUid );
    pluginInfo->iPlugin->SetQueue( pluginInfo->iQueue );
    pluginInfo->iPlugin->SetHarvesterPluginFactory( *this );
#endif
    
    iHarvesterPluginInfoArray.AppendL( pluginInfo );
    CleanupStack::Pop( pluginInfo );
    }

void CHarvesterPluginFactory::GetSupportedPluginsL(
		RPointerArray<CHarvesterPluginInfo>& aSupportedPlugins, const TDesC& aExt )
	{
    CleanupResetAndDestroyPushL( aSupportedPlugins );
    
	const TInt pluginInfoCount = iHarvesterPluginInfoArray.Count();
	TInt extCount = 0;
	for ( TInt i = pluginInfoCount; --i >= 0; )
        {
        CHarvesterPluginInfo* info = iHarvesterPluginInfoArray[i];
        
        extCount = info->iExtensions.Count();
        for ( TInt k = extCount; --k >= 0; )
            {
            TDesC* ext = info->iExtensions[k];
            
            // checking against supported plugin file extensions
            const TInt result = ext->CompareF( aExt );
            if ( result == 0 )
                {
                aSupportedPlugins.AppendL( info );
                break;
                }
            }
        }	
	
	CleanupStack::Pop( &aSupportedPlugins );
	}

EXPORT_C TBool CHarvesterPluginFactory::IsSupportedFileExtension( const TDesC& aFileName )
	{
	TPtrC extPtr;
	if( MdsUtils::GetExt( aFileName, extPtr ) )
		{
		TInt pluginInfoCount = iHarvesterPluginInfoArray.Count();
		TInt extCount = 0;
		for ( TInt i = pluginInfoCount; --i >= 0; )
			{
			CHarvesterPluginInfo* info = iHarvesterPluginInfoArray[i];
			extCount = info->iExtensions.Count();
			for ( TInt k = extCount; --k >= 0; )
				{
				TDesC* ext = info->iExtensions[k];
				// checking against supported plugin file extensions
				TInt result = MdsUtils::Compare( *ext, extPtr );
				if ( result == 0 )
					{
					return ETrue;
					}
				}
			}
		}
	return EFalse;
	}

EXPORT_C TBool CHarvesterPluginFactory::IsContainerFileL( const TDesC& aURI )
	{
	TBool isContainerFile = EFalse;
	TPtrC extPtr;
	
	if( MdsUtils::GetExt( aURI, extPtr ) )
		{
		RPointerArray<CHarvesterPluginInfo> supportedPlugins;
		CleanupClosePushL( supportedPlugins );
		GetSupportedPluginsL( supportedPlugins, extPtr );
		for( TInt i = supportedPlugins.Count() - 1; i >=0; i-- )
			{
			CHarvesterPluginInfo* info = supportedPlugins[i];
			if( info->iObjectTypes.Count() >  1 )
				{
				isContainerFile = ETrue;
				break;
				}
			}
		CleanupStack::PopAndDestroy( &supportedPlugins );
		}
	return isContainerFile;
	}

void CHarvesterPluginFactory::SetPluginInfo( CHarvesterData* aHD )
    {
    TPtrC extPtr;
    if( MdsUtils::GetExt( aHD->Uri(), extPtr ) )
        {
        RPointerArray<CHarvesterPluginInfo> supportedPlugins;
        TRAP_IGNORE( GetSupportedPluginsL( supportedPlugins, extPtr ) );
        
        if( supportedPlugins.Count() > 0 )
            {
            CHarvesterPluginInfo* info = supportedPlugins[0];
            aHD->SetHarvesterPluginInfo( info );
            }

        supportedPlugins.Close();
        }
    }

EXPORT_C void CHarvesterPluginFactory::SendHarvestingStatusEventL( TBool aStarted )
    {
    const TInt pluginInfoCount = iHarvesterPluginInfoArray.Count();
    TBool itemsLeft( EFalse );
    TBool allPluginsOnIdle( ETrue );
    for ( TInt i = pluginInfoCount; --i >= 0; )
        {
        CHarvesterPluginInfo* info = iHarvesterPluginInfoArray[i];
        if( info && info->iQueue.Count() )
            {
            itemsLeft = ETrue;
            if( aStarted )
                {
                // Idle state is only checked if finished event is sent
                break;
                }
            }
        if( info && info->iPlugin && !(info->iPlugin->PluginInIdleState()) )
            {
            allPluginsOnIdle = EFalse;
            }
        }
    
    if( !iHarvesting && itemsLeft && aStarted )
        {
        iHarvesting = ETrue;
        iHarvesterEventManager->SendEventL( EHEObserverTypeOverall, EHEStateStarted );
        // This next line is for caching the harvester started event for observers registering
        // after harvesting has already started
        iHarvesterEventManager->IncreaseItemCount( EHEObserverTypeOverall, KCacheItemCountForEventCaching );
        return;
        }
    else if( iHarvesting && (!itemsLeft || allPluginsOnIdle) && !aStarted )
        {
        iHarvesting = EFalse;                       
        iHarvesterEventManager->SendEventL( EHEObserverTypeOverall, EHEStateFinished );
        iHarvesterEventManager->DecreaseItemCountL( EHEObserverTypeOverall, KCacheItemCountForEventCaching );
        }
    }

EXPORT_C void CHarvesterPluginFactory::PauseHarvester( TBool aPaused )
    {
    const TInt count = iHarvesterPluginInfoArray.Count();
    for ( TInt i = count; --i >= 0; )
        {
        if( iHarvesterPluginInfoArray[i]->iPlugin && aPaused )
            {
            iHarvesterPluginInfoArray[i]->iPlugin->Cancel();
            }
        else if( iHarvesterPluginInfoArray[i]->iPlugin )
            {
            iHarvesterPluginInfoArray[i]->iPlugin->StartHarvest();
            }
        }
    }