diff -r cad71a31b7fc -r e36f3802f733 srsf/vuiphandler/src/nssvoiceuipluginhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srsf/vuiphandler/src/nssvoiceuipluginhandler.cpp Wed Sep 01 12:29:17 2010 +0100 @@ -0,0 +1,327 @@ +/* +* Copyright (c) 2005 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: Implementation of VoiceUIPluginHandler +* +*/ + + +// INCLUDE FILES +#include +#include +#include "nssvoiceuipluginhandler.h" +#include "rubydebug.h" +#include + + +// CONSTANTS +const TUid KEventPluginUid = { KVuipfEventInterfaceUid }; +const TUid KActionPluginUid = { KVuipfExecutionInterfaceUid }; + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::CNssVoiceUIPluginHandler +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CNssVoiceUIPluginHandler::CNssVoiceUIPluginHandler() + { + // nothing + } + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CNssVoiceUIPluginHandler::ConstructL() + { + LoadPluginsL(); + } + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CNssVoiceUIPluginHandler* CNssVoiceUIPluginHandler::NewL() + { + RUBY_DEBUG_BLOCK( "CNssVoiceUIPluginHandler::NewL()" ); + CNssVoiceUIPluginHandler* self = new( ELeave ) CNssVoiceUIPluginHandler; + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::~CNssVoiceUIPluginHandler +// Destructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CNssVoiceUIPluginHandler::~CNssVoiceUIPluginHandler() + { + UnloadPlugins(); + RUBY_DEBUG0( "CNssVoiceUIPluginHandler::~CNssVoiceUIPluginHandler() end" ); + } + + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::VoiceEvent +// Handle voice event +// ----------------------------------------------------------------------------- +// +TInt CNssVoiceUIPluginHandler::VoiceEvent( TUid aEventUid ) + { + RUBY_DEBUG1( "CNssVoiceUIPluginHandler::VoiceEvent(0x%x)", aEventUid.iUid ); + CVoiceUiPluginBase* plugin = NULL; + CVoiceUiPluginBase* previousPlugin = NULL; + TInt highestPriority( KMinTInt ); + + RPointerArray usedPlugins; + // Select the suitable plug-in with highest priority + // In case of multiple plug-ins with same priority the first one is selected. + + TInt status( KErrNoneEventNotConsumed ); + + // execute plug-ins until the event has been successfully processed + while ( status != KErrNone ) + { + + // Loop all plugins + for( TInt i( 0 ); i < iActionPlugins.Count(); i++ ) + { + CVoiceUiPluginBase* tmpPlugin = iActionPlugins[i]; + + // Loop all supported events in the plugin + for ( TInt j( 0 ); j < tmpPlugin->EventUids().Count(); j++ ) + { + RUBY_DEBUG2( "VoiceEvent Comparing event uid [0x%x] against plugin's [0x%x]", + aEventUid.iUid, tmpPlugin->EventUids()[j].iUid ); + + TVuipPriority priority = tmpPlugin->Priority(); + if ( tmpPlugin->EventUids()[j] == aEventUid + && priority > highestPriority ) + { + + // find the next plug-in in the order of priority + TBool alreadyUsed( EFalse ); + TInt k( 0 ); + while( k < usedPlugins.Count() && !alreadyUsed ) + { + if ( usedPlugins[k] == tmpPlugin ) + { + alreadyUsed = ETrue; + } + k++; + } + + if ( !alreadyUsed ) + { + plugin = tmpPlugin; + highestPriority = priority; + } + } + } + } + + if ( plugin && plugin != previousPlugin ) + { + // execute a plug-in + status = plugin->Execute( aEventUid ); + previousPlugin = plugin; + } + else + { + // all plug-ins checked -> exit loop + RUBY_DEBUG0( "No plugin for the event"); + break; + } + } + + + if ( status == KErrNoneForwardEvent ) + { + status = KErrNoneEventNotConsumed; + } + + usedPlugins.Reset(); + usedPlugins.Close(); + return status; + } + + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::LoadPluginsL +// Loads plug-ins +// ----------------------------------------------------------------------------- +// +void CNssVoiceUIPluginHandler::LoadPluginsL() + { + RUBY_DEBUG_BLOCK( "CNssVoiceUIPluginHandler::LoadPluginsL()" ); + TInt i( 0 ); + RImplInfoPtrArray eventPluginArray; + CleanupClosePushL( eventPluginArray ); + + REComSession::ListImplementationsL( KEventPluginUid, eventPluginArray ); + + RUBY_DEBUG1( "CNssVoiceUIPluginHandler::LoadPluginsL() found %i event plugins", + eventPluginArray.Count() ); + // load event plug-ins + for ( i = 0; i < eventPluginArray.Count(); i++ ) + { + // Get Uid of plug-in + TUid id = eventPluginArray[i]->ImplementationUid(); + + // create plug-in + TUid dtorID; + CVoiceEventObserverPluginBase* tmpPlugin = NULL; + + TRAPD( error, + tmpPlugin = + reinterpret_cast + ( REComSession::CreateImplementationL( id, dtorID ) ) ); + + if ( error == KErrNone ) + { + // initialize plug-in + TRAP( error, tmpPlugin->InitializeL( *this ) ); + } + + if ( error == KErrNone ) + { + error = iEventPlugins.Append( tmpPlugin ); + } + + if ( error == KErrNone ) + { + error = iEventPluginDtorIds.Append( dtorID ); + } + + if ( error != KErrNone ) + { + REComSession::DestroyedImplementation( dtorID ); + delete tmpPlugin; + tmpPlugin = NULL; + } + + } + + eventPluginArray.ResetAndDestroy(); + + CleanupStack::PopAndDestroy( &eventPluginArray ); + + RImplInfoPtrArray actionPluginArray; + CleanupClosePushL( actionPluginArray ); + REComSession::ListImplementationsL( KActionPluginUid, actionPluginArray ); + + RUBY_DEBUG1( "CNssVoiceUIPluginHandler::LoadPluginsL() found %i VUI plugins", + actionPluginArray.Count() ); + + // load action plug-ins + for ( i = 0; i < actionPluginArray.Count(); i++ ) + { + // Get Uid of plug-in + TUid id = actionPluginArray[i]->ImplementationUid(); + + // create plug-in + TUid dtorID; + CVoiceUiPluginBase* tmpPlugin = NULL; + + TRAPD( error, + tmpPlugin = + reinterpret_cast + ( REComSession::CreateImplementationL( id,dtorID ) ) ); + + if ( error == KErrNone ) + { + // initialize plug-in + TRAP( error, tmpPlugin->InitializeL() ); + } + + if ( error == KErrNone ) + { + error = iActionPlugins.Append( tmpPlugin ); + } + + if ( error == KErrNone ) + { + error = iActionPluginDtorIds.Append( dtorID ); + } + + if ( error != KErrNone ) + { + REComSession::DestroyedImplementation( dtorID ); + delete tmpPlugin; + tmpPlugin = NULL; + } + } + + actionPluginArray.ResetAndDestroy(); + CleanupStack::PopAndDestroy( &actionPluginArray ); + + } + +// ----------------------------------------------------------------------------- +// CNssVoiceUIPluginHandler::UnloadPlugins +// Unloads plug-ins +// ----------------------------------------------------------------------------- +// +void CNssVoiceUIPluginHandler::UnloadPlugins() + { + TInt i( 0 ); + iEventPlugins.ResetAndDestroy(); + iEventPlugins.Close(); + + // notify ecom + for ( i = 0; i < iEventPluginDtorIds.Count(); i++ ) + { + REComSession::DestroyedImplementation( iEventPluginDtorIds[i] ); + } + + iEventPluginDtorIds.Close(); + iActionPlugins.ResetAndDestroy(); + iActionPlugins.Close(); + + // notify ecom + for ( i = 0; i < iActionPluginDtorIds.Count(); i++ ) + { + REComSession::DestroyedImplementation( iActionPluginDtorIds[i] ); + } + iActionPluginDtorIds.Close(); + + // Release REComSession allocations. + REComSession::FinalClose(); + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// ----------------------------------------------------------------------------- +// For DLL goodness. +// ----------------------------------------------------------------------------- +// +#ifndef EKA2 +GLDEF_C TInt E32Dll( TDllReason /*aReason*/ ) + { + return KErrNone; + } +#endif + +// End of File