idlefw/tsrc/framework/ut_aifw/stub/src/aipluginfactory_stub.cpp
branchRCL_3
changeset 110 2c7f27287390
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlefw/tsrc/framework/ut_aifw/stub/src/aipluginfactory_stub.cpp	Thu Jul 15 18:59:18 2010 +0300
@@ -0,0 +1,776 @@
+/*
+* Copyright (c) 2005-2006 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:  Content publisher factory stub
+*
+*/
+
+// System includes
+#include <ecom/ecom.h>
+#include <ecom/implementationinformation.h>
+
+// 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_stub.h"
+#include "aistatemanager.h"
+#include "aipluginfactory_stub.h"
+#include "debug.h"
+
+// Constants
+const TUid KDeviceStatusPluginUid = 
+    { AI_UID_ECOM_IMPLEMENTATION_CONTENTPUBLISHER_DEVSTAPLUGIN };
+
+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 ========
+// ----------------------------------------------------------------------------
+// IsRecyclable()
+//
+// ----------------------------------------------------------------------------
+//
+TBool IsRecyclable( const THsPublisherInfo& aInfo )
+    {
+    if ( ( aInfo.Name() == KProfilePluginName && 
+        aInfo.Uid() == KProfilePluginUid ) ||
+        ( aInfo.Name() == KDeviceStatusPluginName &&
+        aInfo.Uid() == KDeviceStatusPluginUid ) )
+        {
+        return ETrue;
+        }
+    
+    return EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// IsSapiOrWrt()
+//
+// ----------------------------------------------------------------------------
+//
+TBool IsSapiOrWrt( const THsPublisherInfo& aInfo )
+    {
+    return ( aInfo.Uid() == KSapiPluginImplUid || 
+             aInfo.Uid() == KWrtPluginImplUid );             
+    }
+
+// ----------------------------------------------------------------------------
+// CleanupResetAndDestroy()
+//
+// ----------------------------------------------------------------------------
+//
+template< class T >
+static void CleanupResetAndDestroy( TAny* aObj )
+    {        
+    static_cast< T* >( aObj )->ResetAndDestroy();    
+    }
+
+// ----------------------------------------------------------------------------
+// CleanupResetAndDestroyPushL()
+//
+// ----------------------------------------------------------------------------
+//
+template< class T >
+static void CleanupResetAndDestroyPushL( T& aArray )
+    {
+    CleanupStack::PushL( 
+        TCleanupItem( &CleanupResetAndDestroy< T >, &aArray ) );
+    }
+    
+// ======== MEMBER FUNCTIONS ========    
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::CAiPluginFactory()
+//
+// ----------------------------------------------------------------------------
+//
+CAiPluginFactory::CAiPluginFactory( CAiUiControllerManager& aManager )
+    : CTimer( CActive::EPriorityUserInput - 1 ), 
+      iUiControllerManager( aManager ), iAllowFlush( ETrue )
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::~CAiPluginFactory()
+//
+// ----------------------------------------------------------------------------
+//
+CAiPluginFactory::~CAiPluginFactory()
+    {
+    Cancel();
+    
+    delete iStarter;
+    
+    delete iCommandBuffer;
+    
+    iLoadQueue.Reset();
+    iDestroyQueue.Reset();
+    
+    // All publishers should be already deleted from CAiFw::HandleUiShutdown       
+    iPublishers.ResetAndDestroy();
+    
+    iEComPlugins.ResetAndDestroy();        
+    
+    REComSession::FinalClose();
+    }
+    
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::NewL()
+//
+// ----------------------------------------------------------------------------
+//
+CAiPluginFactory* CAiPluginFactory::NewL( CAiUiControllerManager& aManager )
+    {
+    return new ( ELeave ) CAiPluginFactory( aManager ); 
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::ConstructL()
+//
+// ----------------------------------------------------------------------------
+//
+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 );
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::LoadPlugin()
+//
+// ----------------------------------------------------------------------------
+//
+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()
+//
+// ----------------------------------------------------------------------------
+//
+void CAiPluginFactory::DestroyPlugin( const TAiFwPublisherInfo& aInfo )
+    {
+    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();
+            }    
+        } 
+    }
+
+// ----------------------------------------------------------------------------
+// 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 )
+        {
+        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 ( info.Namespace() == KNullDesC8 )
+                {
+                // No namespace available
+                __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\
+                               Failed to Load Plug-in: KErrNotSupported ***" );
+                return KErrNotSupported;
+                }
+
+            // Plugin already exists, update its namespace
+            THsPublisherInfo& pubinfo( 
+                const_cast< THsPublisherInfo& >( plugin->PublisherInfo() ) );
+
+            pubinfo.iNamespace.Copy( info.Namespace() );
+
+            __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\
+                           Plugin recycled ***" );
+
+            return KErrNone;
+            }
+        }
+
+    TBool implFound( EFalse );
+
+    for( TInt i = 0; i < iEComPlugins.Count(); i++ )
+        {
+        CImplementationInformation* information( iEComPlugins[i] );
+
+        if( information->ImplementationUid() == info.Uid() )
+            {
+            implFound = ETrue;
+            break;
+            }
+        }
+    
+    if( info.Namespace() == KNullDesC8 || !implFound )
+        {
+        // No namespace available or no ecom implementation available
+        __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\
+                       Failed to Load Plug-in: KErrNotSupported ***" );
+        
+        return KErrNotSupported;
+        }
+           
+    CHsContentPublisher* plugin( PluginByInfo( info ) );
+
+    if( plugin )
+        {
+        __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done -\
+                       No need to Load Plug-in: KErrAlreadyExists ***" );
+        
+        return KErrAlreadyExists;
+        }
+
+    TInt err( KErrNone );
+
+    TRAP( err, DoCreatePluginL( aPublisherInfo ) );
+    
+    __PRINTS( "*** CAiPluginFactory::CreatePlugin: Done - Load Plug-in ***" );
+
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::DoDestroyPlugin()
+//
+// ----------------------------------------------------------------------------
+//
+void CAiPluginFactory::DoDestroyPlugin( 
+    const TAiFwPublisherInfo& aPublisherInfo )                             
+    {
+    __PRINTS( "*** CAiPluginFactory::DoDestroyPlugin: Start ***" );
+    
+    const THsPublisherInfo& info( aPublisherInfo.Info() );
+      
+    if ( IsRecyclable( info ) )
+        {
+        // Don't destroy recyclable plugin
+        __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Done - Keeping recyclable Plug-in ***" );
+        
+        return;
+        }
+   
+    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 )
+        {
+        iPublishers.Remove( iPublishers.Find( plugin ) );
+        
+        delete plugin;
+        plugin = NULL;            
+        }
+    
+    __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Done ***" );
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::DestroyPlugin()
+//
+// ----------------------------------------------------------------------------
+//
+void CAiPluginFactory::DestroyPlugin( const TUid& aUid )
+    {
+    __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Start ***" );
+    
+    CHsContentPublisher* plugin( PluginByUid( aUid ) );
+    
+    if ( plugin )
+        {                
+        iPublishers.Remove( iPublishers.Find( plugin ) );
+        
+        __PRINT( __DBG_FORMAT( 
+            "CAiPluginFactory::DestroyPlugin: name: %S" ), 
+                &plugin->PublisherInfo().Name() ); 
+
+        delete plugin;
+        plugin = NULL;                
+        }
+    
+    __PRINTS( "*** CAiPluginFactory::DestroyPlugin: Done ***" );
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::DestroyAllPlugins()
+//
+// ----------------------------------------------------------------------------
+//
+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"), 
+    info.Uid(), &(info.Name() ) );
+
+    iPublishers.ReserveL( iPublishers.Count() + 1 );
+    
+    CHsContentPublisher* plugin( NULL );
+    
+    __TIME( "CAiPluginFactory::CreatePluginL Create plug-in:",                                  
+    plugin = CHsContentPublisher::NewL( info ) );            
+    
+    CleanupStack::PushL( plugin );
+    
+    if ( IsSapiOrWrt( info ) )
+        {
+        plugin->SetProperty( CHsContentPublisher::ECpsCmdBuffer, 
+            static_cast< MAiCpsCommandBuffer* >( iCommandBuffer ) );    
+        }
+    
+    __TIME( "FW: Subscribe content observers",    
+    SubscribePluginL( *plugin, info ) );             
+                                                      
+    __TIME( "FW: Configure Plugin",
+    ConfigurePluginL( *plugin, info ) );
+    
+    // Take plugin's ownership
+    iPublishers.Append( plugin );
+    CleanupStack::Pop( plugin );
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::SubscribePluginL()
+//
+// ----------------------------------------------------------------------------
+//
+void CAiPluginFactory::SubscribePluginL(
+    CHsContentPublisher& aContentPublisher,        
+    const THsPublisherInfo& aPublisherInfo )    
+    {
+    RPointerArray< CAiUiController >& 
+        controllers( iUiControllerManager.UiControllers() );
+            
+    for( TInt i = 0; i < controllers.Count(); i++ )
+        {
+        MAiContentObserver& observer( 
+            controllers[i]->GetContentObserver() );
+        
+        if ( observer.RequiresSubscription( aPublisherInfo ) )
+            {
+			// Subscribe observer only if it understands the plugin
+            aContentPublisher.SubscribeL( observer );
+            }                   
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::ConfigurePluginL()
+//
+// ----------------------------------------------------------------------------
+//
+void CAiPluginFactory::ConfigurePluginL(     
+    CHsContentPublisher& aContentPublisher,
+    const THsPublisherInfo& aPublisherInfo )
+    {    
+    RAiSettingsItemArray settings;
+    CleanupResetAndDestroyPushL( settings );
+    
+    RPointerArray< CAiUiController >& 
+        controllers( iUiControllerManager.UiControllers() );
+    
+    for( TInt i = 0; i < controllers.Count(); i++ )
+        {
+        // Get settings for plug-in        
+        controllers[i]->GetSettingsL( aPublisherInfo, settings );
+        }
+    
+    // Configure plug-in with its settings
+    aContentPublisher.ConfigureL( settings );
+    
+    CleanupStack::PopAndDestroy( &settings );    
+    }
+        
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::PluginByInfo()
+// Gets plugin by publisher info. Only this overload returns the exact match
+// ----------------------------------------------------------------------------
+//
+CHsContentPublisher* CAiPluginFactory::PluginByInfo( 
+    const THsPublisherInfo& aPublisherInfo ) const
+    {       
+    for( TInt i = 0; i < iPublishers.Count(); i++ )
+        {         
+        const THsPublisherInfo& info( iPublishers[i]->PublisherInfo() ); 
+                                                                             
+        if( aPublisherInfo == info ) 
+            {
+            return iPublishers[i];
+            }
+        }
+    
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::PluginByUid()
+// Gets plugin by UID
+// ----------------------------------------------------------------------------
+//
+CHsContentPublisher* CAiPluginFactory::PluginByUid( const TUid& aUid ) const
+    {
+    for( TInt i = 0; i < iPublishers.Count(); i++ )
+        {
+        const THsPublisherInfo& info( iPublishers[i]->PublisherInfo() );
+                                                               
+        if( info.Uid() == aUid )
+            {
+            return iPublishers[i];            
+            }
+        }
+    
+    return NULL;        
+    }
+    
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::PluginByName()
+// Gets plugin by name
+// ----------------------------------------------------------------------------
+//
+CHsContentPublisher* CAiPluginFactory::PluginByName( 
+    const TDesC& aName ) const
+    {
+    for( TInt i = 0; i < iPublishers.Count(); i++ )
+        {
+        const THsPublisherInfo& info( iPublishers[i]->PublisherInfo() );
+                                                               
+        if( info.Name() == aName )
+            {
+            return iPublishers[i];            
+            }
+        }
+    
+    return NULL;    
+    }
+
+// ----------------------------------------------------------------------------
+// CAiPluginFactory::Publishers()
+//
+// ----------------------------------------------------------------------------
+//
+RPointerArray< CHsContentPublisher >& CAiPluginFactory::Publishers() const
+    {
+    return iPublishers;
+    }
+
+// ----------------------------------------------------------------------------
+// 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::RunL()
+    {
+    __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