diff -r b276298d5729 -r edd621764147 idlefw/src/framework/aipluginfactory.cpp --- a/idlefw/src/framework/aipluginfactory.cpp Tue Apr 27 16:57:49 2010 +0300 +++ b/idlefw/src/framework/aipluginfactory.cpp Tue May 11 16:30:05 2010 +0300 @@ -21,12 +21,14 @@ // User includes #include +#include #include #include #include #include #include "caicpscommandbuffer.h" #include "aiuicontrollermanager.h" +#include "aistatemanager.h" #include "aipluginfactory.h" #include "debug.h" @@ -37,9 +39,13 @@ const TUid KProfilePluginUid = { AI_UID_ECOM_IMPLEMENTATION_CONTENTPUBLISHER_PROFILEPLUGIN }; +const TUid KSapiPluginImplUid = { 0x20019594 }; +const TUid KWrtPluginImplUid = { 0x200286DD }; + _LIT( KDeviceStatusPluginName, "DeviceStatus" ); _LIT( KProfilePluginName, "Profile" ); +const TInt KQueueStartInterval( 500000 ); // ======== LOCAL FUNCTIONS ======== // ---------------------------------------------------------------------------- @@ -61,6 +67,17 @@ } // ---------------------------------------------------------------------------- +// IsSapiOrWrt() +// +// ---------------------------------------------------------------------------- +// +TBool IsSapiOrWrt( const THsPublisherInfo& aInfo ) + { + return ( aInfo.Uid() == KSapiPluginImplUid || + aInfo.Uid() == KWrtPluginImplUid ); + } + +// ---------------------------------------------------------------------------- // CleanupResetAndDestroy() // // ---------------------------------------------------------------------------- @@ -91,7 +108,8 @@ // ---------------------------------------------------------------------------- // CAiPluginFactory::CAiPluginFactory( CAiUiControllerManager& aManager ) - : iUiControllerManager( aManager ) + : CTimer( CActive::EPriorityUserInput - 1 ), + iUiControllerManager( aManager ), iAllowFlush( ETrue ) { } @@ -102,6 +120,15 @@ // CAiPluginFactory::~CAiPluginFactory() { + Cancel(); + + delete iStarter; + + delete iCommandBuffer; + + iLoadQueue.Reset(); + iDestroyQueue.Reset(); + // All publishers should be already deleted from CAiFw::HandleUiShutdown iPublishers.ResetAndDestroy(); @@ -117,13 +144,7 @@ // CAiPluginFactory* CAiPluginFactory::NewL( CAiUiControllerManager& aManager ) { - CAiPluginFactory* self = - new ( ELeave ) CAiPluginFactory( aManager ); - - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; + return new ( ELeave ) CAiPluginFactory( aManager ); } // ---------------------------------------------------------------------------- @@ -132,28 +153,172 @@ // ---------------------------------------------------------------------------- // void CAiPluginFactory::ConstructL() - { + { + ListImplementationsL(); + + iCommandBuffer = CAiCpsCommandBuffer::NewL(); + + // Ensure interface is available + iCommandBuffer->GetCPSInterfaceL(); + + CActiveScheduler::Add( this ); + + CTimer::ConstructL(); + + iStarter = CPeriodic::NewL( CActive::EPriorityIdle ); + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::ListImplementationsL() +// +// ---------------------------------------------------------------------------- +// +void CAiPluginFactory::ListImplementationsL() + { + iEComPlugins.ResetAndDestroy(); + REComSession::ListImplementationsL( - KInterfaceUidHsContentPlugin, iEComPlugins ); + KInterfaceUidHsContentPlugin, iEComPlugins ); } - + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::LoadPlugin() +// // ---------------------------------------------------------------------------- -// CAiPluginFactory::CreatePluginL() +// +void CAiPluginFactory::LoadPlugin( const TAiFwPublisherInfo& aInfo ) + { + const THsPublisherInfo& info( aInfo.Info() ); + + for ( TInt i = 0; i < iDestroyQueue.Count(); i++ ) + { + if ( iDestroyQueue[i] == info ) + { + iDestroyQueue.Remove( i ); + break; + } + } + + if ( IsSapiOrWrt( info ) || IsRecyclable( info ) || !PluginByInfo( info ) ) + { + TBool append( ETrue ); + + for ( TInt i = 0; i < iLoadQueue.Count(); i++ ) + { + if ( iLoadQueue[i] == info ) + { + append = EFalse; + break; + } + } + + // Plugin is not in load queue and is not currently loaded + if( append ) + { + iLoadQueue.Append( aInfo ); + + HandleQueueChanged(); + } + } + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::DestroyPlugin() // // ---------------------------------------------------------------------------- // -TInt CAiPluginFactory::CreatePlugin( - const THsPublisherInfo& aPublisherInfo ) +void CAiPluginFactory::DestroyPlugin( const TAiFwPublisherInfo& aInfo ) { - __PRINTS( "*** CAiPluginFactory::CreatePlugin: Start ***" ); + const THsPublisherInfo& info( aInfo.Info() ); + + for ( TInt i = 0; i < iLoadQueue.Count(); i++ ) + { + if ( iLoadQueue[i] == info ) + { + iLoadQueue[i].Callback( KErrCancel ); + + iLoadQueue.Remove( i ); + break; + } + } + + if ( PluginByInfo( info ) ) + { + TBool append( ETrue ); + + for ( TInt i = 0; i < iDestroyQueue.Count(); i++ ) + { + if ( iDestroyQueue[i] == info ) + { + append = EFalse; + break; + } + } + + // Plugin is not in destroy queue and is currently loaded + if ( append ) + { + iDestroyQueue.Append( aInfo ); + + HandleQueueChanged(); + } + } + } - if ( IsRecyclable( aPublisherInfo ) ) +// ---------------------------------------------------------------------------- +// CAiPluginFactory::HandleQueueChanged() +// +// ---------------------------------------------------------------------------- +// +void CAiPluginFactory::HandleQueueChanged() + { + __PRINTS( "CAiPluginFactory::HandleQueueChanged" ); + + if ( iLoadQueue.Count() == 0 && iDestroyQueue.Count() == 0 ) + { + __PRINTS( "CAiPluginFactory::HandleQueueChanged - done, queues empty" ); + + return; + } + + Cancel(); + iStarter->Cancel(); + + __PRINTS( "CAiPluginFactory::HandleQueueChanged, iStarter->Start()" ); + + if ( iLoadQueue.Count() == 1 && iDestroyQueue.Count() == 0 && + iLoadQueue[0].Reason() == EAiFwPluginStartup ) { - CHsContentPublisher* plugin( PluginByUid( aPublisherInfo.Uid() ) ); + ProcessQueue( this ); + } + else + { + iStarter->Start( KQueueStartInterval, 0, + TCallBack( ProcessQueue, this ) ); + } + + __PRINTS( "CAiPluginFactory::HandleQueueChanged - done" ); + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::DoCreatePlugin() +// +// ---------------------------------------------------------------------------- +// +TInt CAiPluginFactory::DoCreatePlugin( + const TAiFwPublisherInfo& aPublisherInfo ) + { + __PRINTS( "*** CAiPluginFactory::DoCreatePlugin: Start ***" ); + + const THsPublisherInfo& info( aPublisherInfo.Info() ); + + if ( IsRecyclable( info ) ) + { + CHsContentPublisher* plugin( PluginByUid( info.Uid() ) ); if ( plugin ) { - if ( aPublisherInfo.Namespace() == KNullDesC8 ) + if ( info.Namespace() == KNullDesC8 ) { // No namespace available __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\ @@ -162,10 +327,10 @@ } // Plugin already exists, update its namespace - THsPublisherInfo& info( + THsPublisherInfo& pubinfo( const_cast< THsPublisherInfo& >( plugin->PublisherInfo() ) ); - info.iNamespace.Copy( aPublisherInfo.Namespace() ); + pubinfo.iNamespace.Copy( info.Namespace() ); __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\ Plugin recycled ***" ); @@ -180,14 +345,14 @@ { CImplementationInformation* information( iEComPlugins[i] ); - if( information->ImplementationUid().iUid == aPublisherInfo.Uid().iUid ) + if( information->ImplementationUid() == info.Uid() ) { implFound = ETrue; break; } } - if( aPublisherInfo.Namespace() == KNullDesC8 || !implFound ) + if( info.Namespace() == KNullDesC8 || !implFound ) { // No namespace available or no ecom implementation available __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\ @@ -196,19 +361,19 @@ return KErrNotSupported; } - CHsContentPublisher* plugin( PluginByInfo( aPublisherInfo ) ); + CHsContentPublisher* plugin( PluginByInfo( info ) ); if( plugin ) { __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\ - Failed to Load Plug-in: KErrAlreadyExists ***" ); + No need to Load Plug-in: KErrAlreadyExists ***" ); return KErrAlreadyExists; } TInt err( KErrNone ); - TRAP( err, CreatePluginL( aPublisherInfo ) ); + TRAP( err, DoCreatePluginL( aPublisherInfo ) ); __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done - Load Plug-in ***" ); @@ -216,23 +381,37 @@ } // ---------------------------------------------------------------------------- -// CAiPluginFactory::DestroyPlugin() +// CAiPluginFactory::DoDestroyPlugin() // // ---------------------------------------------------------------------------- // -void CAiPluginFactory::DestroyPlugin( const THsPublisherInfo& aPublisherInfo ) +void CAiPluginFactory::DoDestroyPlugin( + const TAiFwPublisherInfo& aPublisherInfo ) { - __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Start ***" ); + __PRINTS( "*** CAiPluginFactory::DoDestroyPlugin: Start ***" ); - if ( IsRecyclable( aPublisherInfo ) ) + const THsPublisherInfo& info( aPublisherInfo.Info() ); + + if ( IsRecyclable( info ) ) { // Don't destroy recyclable plugin __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Done - Keeping recyclable Plug-in ***" ); return; } - - CHsContentPublisher* plugin( PluginByInfo( aPublisherInfo ) ); + + if ( IsSapiOrWrt( info ) ) + { + if ( aPublisherInfo.Reason() == EAiFwPageShutdown ) + { + // Don't destroy sapi or wrt plugin when page is changed + __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Done - Keeping SAPI/WRT plugin ***" ); + + return; + } + } + + CHsContentPublisher* plugin( PluginByInfo( info ) ); if ( plugin ) { @@ -256,51 +435,81 @@ CHsContentPublisher* plugin( PluginByUid( aUid ) ); - while ( plugin ) - { + if ( plugin ) + { iPublishers.Remove( iPublishers.Find( plugin ) ); __PRINT( __DBG_FORMAT( - "CAiPluginFactory::DestroyPlugin: name: %S" ), &plugin->PublisherInfo().Name() ); + "CAiPluginFactory::DestroyPlugin: name: %S" ), + &plugin->PublisherInfo().Name() ); delete plugin; - plugin = NULL; + plugin = NULL; } __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Done ***" ); } // ---------------------------------------------------------------------------- -// CAiPluginFactory::CreatePluginL() +// CAiPluginFactory::DestroyAllPlugins() // // ---------------------------------------------------------------------------- // -void CAiPluginFactory::CreatePluginL( - const THsPublisherInfo& aPublisherInfo ) +void CAiPluginFactory::DestroyAllPlugins() { + Cancel(); + iStarter->Cancel(); + + iLoadQueue.Reset(); + iDestroyQueue.Reset(); + + for ( TInt i = 0; i < iPublishers.Count(); i++ ) + { + CHsContentPublisher* plugin( iPublishers[i] ); + + // Do shutdown state transition + iStateManager->StopPlugin( *plugin, EAiFwSystemShutdown ); + } + + FlushCommandBuffer(); + + // Finally get rid of all plugins + iPublishers.ResetAndDestroy(); + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::DoCreatePluginL() +// +// ---------------------------------------------------------------------------- +// +void CAiPluginFactory::DoCreatePluginL( + const TAiFwPublisherInfo& aPublisherInfo ) + { + const THsPublisherInfo& info( aPublisherInfo.Info() ); + __PRINT( __DBG_FORMAT( "\t[I]\t Loading plug-in uid=%x name=%S"), - aPublisherInfo.Uid(), &(aPublisherInfo.Name() ) ); + info.Uid(), &(info.Name() ) ); iPublishers.ReserveL( iPublishers.Count() + 1 ); CHsContentPublisher* plugin( NULL ); __TIME( "CAiPluginFactory::CreatePluginL Create plug-in:", - plugin = CHsContentPublisher::NewL( aPublisherInfo ) ); + plugin = CHsContentPublisher::NewL( info ) ); CleanupStack::PushL( plugin ); - // Ensure interface is available - iCommandBuffer->GetCPSInterfaceL(); - - plugin->SetProperty( CHsContentPublisher::ECpsCmdBuffer, - static_cast< MAiCpsCommandBuffer* >( iCommandBuffer ) ); + if ( IsSapiOrWrt( info ) ) + { + plugin->SetProperty( CHsContentPublisher::ECpsCmdBuffer, + static_cast< MAiCpsCommandBuffer* >( iCommandBuffer ) ); + } __TIME( "FW: Subscribe content observers", - SubscribeContentObserversL( *plugin, aPublisherInfo ) ); + SubscribePluginL( *plugin, info ) ); __TIME( "FW: Configure Plugin", - ConfigurePluginL( *plugin, aPublisherInfo ) ); + ConfigurePluginL( *plugin, info ) ); // Take plugin's ownership iPublishers.Append( plugin ); @@ -308,11 +517,11 @@ } // ---------------------------------------------------------------------------- -// CAiPluginFactory::SubscribeContentObserversL() +// CAiPluginFactory::SubscribePluginL() // // ---------------------------------------------------------------------------- // -void CAiPluginFactory::SubscribeContentObserversL( +void CAiPluginFactory::SubscribePluginL( CHsContentPublisher& aContentPublisher, const THsPublisherInfo& aPublisherInfo ) { @@ -432,13 +641,136 @@ } // ---------------------------------------------------------------------------- -// CAiPluginFactory::SetCommandBuffer() +// CAiPluginFactory::SetStateManager() +// +// ---------------------------------------------------------------------------- +// +void CAiPluginFactory::SetStateManager( CAiStateManager* aStateManager ) + { + iStateManager = aStateManager; + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::FlushCommandBuffer() +// +// ---------------------------------------------------------------------------- +// +void CAiPluginFactory::FlushCommandBuffer() + { + __PRINTS( "CAiPluginFactory::FlushCommandBuffer" ); + + if ( iCommandBuffer && iAllowFlush && !IsActive() ) + { + iCommandBuffer->Flush(); + } + + __PRINTS( "CAiPluginFactory::FlushCommandBuffer - done" ); + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::ProcessQueue() +// +// ---------------------------------------------------------------------------- +// +/* static */ TInt CAiPluginFactory::ProcessQueue( TAny* aAny ) + { + CAiPluginFactory* self = static_cast< CAiPluginFactory* >( aAny ); + + self->iStarter->Cancel(); + + if ( !self->IsActive() ) + { + self->After( 0 ); + } + + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::RunL() // // ---------------------------------------------------------------------------- // -void CAiPluginFactory::SetCommandBuffer( CAiCpsCommandBuffer* aCommandBuffer ) +void CAiPluginFactory::RunL() { - iCommandBuffer = aCommandBuffer; + __PRINTS( "CAiPluginFactory::RunL" ); + + if ( iStarter->IsActive() ) + { + __PRINTS( "CAiPluginFactory::RunL - done, iStarter->IsActive()" ); + + return; + } + + iAllowFlush = EFalse; + + if ( iDestroyQueue.Count() > 0 ) + { + TAiFwPublisherInfo info( iDestroyQueue[ 0 ] ); + iDestroyQueue.Remove( 0 ); + + // Resolve plugin + CHsContentPublisher* plugin( PluginByInfo( info.Info() ) ); + + if ( plugin ) + { + // Do shutdown state transition + iStateManager->StopPlugin( *plugin, info.Reason() ); + + // Destroy plugin + DoDestroyPlugin( info ); + } + } + else if ( iLoadQueue.Count() > 0 ) + { + TAiFwPublisherInfo info( iLoadQueue[ 0 ] ); + iLoadQueue.Remove( 0 ); + + // Create plugin + TInt retval( DoCreatePlugin( info ) ); + + if ( retval == KErrNone || retval == KErrAlreadyExists ) + { + CHsContentPublisher* plugin( PluginByInfo( info.Info() ) ); + + if( plugin ) + { + // Do startup state transition + iStateManager->StartPlugin( *plugin, info.Reason() ); + } + else + { + retval = KErrNotFound; + } + } + + info.Callback( retval ); + } + + iAllowFlush = ETrue; + + After( 0 ); + + if ( iLoadQueue.Count() == 0 && iDestroyQueue.Count() == 0 ) + { + __PRINTS( "CAiPluginFactory::RunL - queues now empty" ); + + Cancel(); + + FlushCommandBuffer(); + } + + __PRINTS( "CAiPluginFactory::RunL - done" ); + } + +// ---------------------------------------------------------------------------- +// CAiPluginFactory::DoCancel() +// +// ---------------------------------------------------------------------------- +// +void CAiPluginFactory::DoCancel() + { + __PRINTS( "CAiPluginFactory::DoCancel" ); } // End of file