--- 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 <aisystemuids.hrh>
+#include <aifwpublisherinfo.h>
#include <hscontentpublisher.h>
#include <hspublisherinfo.h>
#include <aicontentobserver.h>
#include <aiuicontroller.h>
#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