featuremgmt/featuremgr/src/serverexe/featmgrserver.cpp
changeset 0 08ec8eefde2f
child 6 5ffdb8f2067f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/featuremgmt/featuremgr/src/serverexe/featmgrserver.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,916 @@
+// Copyright (c) 2007-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:
+//
+
+
+
+
+// INCLUDE FILES
+#include <ecom/ecom.h>
+#include <e32uid.h>
+#include "featmgrconfiguration.h"
+#include "featmgrserver.h"
+#include "featmgrsession.h"
+#include "featmgrpluginhandler.h"
+#include "featmgrdebug.h"
+#include "featmgrsecuritypolicy.h"
+#include <f32file.h>
+#include <s32file.h>
+
+// LOCAL CONSTANTS AND MACROS
+#ifdef EXTENDED_FEATURE_MANAGER_TEST
+_LIT( KPanicCategory, "EnhancedFeatMgrServer" );
+#else
+_LIT( KPanicCategory, "FeatMgrServer" );
+#endif // EXTENDED_FEATURE_MANAGER_TEST
+
+// LOCAL FUNCTION PROTOTYPES
+TInt E32Main(); // Process entry point
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::CFeatMgrServer
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CFeatMgrServer::CFeatMgrServer( const TInt aPriority, const TServerType aType  )
+    :
+    CPolicyServer( aPriority, KFeatMgrPlatSecPolicy, aType ), iBurState(this),
+    iPluginsReady(EFalse), 
+    iPluginsDeleted( EFalse ),
+    iPendingRequests( ETrue ),
+    iFeaturesReady(EFalse)
+    
+    {
+    // Nothing to do
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CFeatMgrServer::ConstructL()
+    {
+    FUNC_LOG
+    
+#ifndef EXTENDED_FEATURE_MANAGER_TEST
+    // Set server process system critical
+    User::SetProcessCritical(User::ESystemCritical);
+#else
+    iShutdown.ConstructL();
+    // ensure the server still exits even if the 1st client fails to connect
+    if( !iShutdown.IsActive() )
+        {
+        iShutdown.Start();
+        }
+#endif
+    
+    // Add server to active scheduler
+    StartL( KServerProcessName );
+    
+    // Connect to file server.
+    User::LeaveIfError( iFs.Connect() );
+    
+    // register BUR
+    iBackupNotification = CBaBackupSessionWrapper::NewL();
+    
+    // register the file 
+	TFileName temp( iRegistry->GetFeaturesFilePathAndName() );
+    iBackupNotification->RegisterFileL( temp, *this );
+	
+    // feature registry
+    iRegistry = CFeatMgrFeatureRegistry::NewL( iFs, *this );
+    
+    TRAPD(err,iRegistry->ReadFeatureFilesL());
+    switch (err)
+    	{
+    	case KErrNotFound:
+    		ERROR_LOG( "CFeatMgrServer::ConstructL() - no feature files found in ROM - going to panic");
+    		User::Panic( KPanicCategory, EPanicNoFeatureFiles );
+    		break;
+    	case KErrCorrupt:
+    	    ERROR_LOG( "CFeatMgrServer::ConstructL() - feature information in ROM is invalid - going to panic");
+    	    User::Panic( KPanicCategory, EPanicInvalidFeatureInfo );
+    	    break;
+    	default:
+    		User::LeaveIfError(err);
+    		break;
+    	}
+	
+    // List and load plugins and feature info.
+    TBool found = LoadPluginsL();
+    
+    if( found )
+        {
+        // Timer for deleting plugins and for comparing feature lists.
+        iTimer = CFeatMgrTimer::NewL( *this );
+       }
+    else
+        {
+        iRegistry->ReadRuntimeFeaturesL( iFeaturesReady );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CFeatMgrServer* CFeatMgrServer::NewLC(const TInt aPriority)
+    {
+    FUNC_LOG
+
+    CFeatMgrServer* self = new( ELeave ) CFeatMgrServer(aPriority, EUnsharableSessions);
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+
+    return self;
+    }
+
+#ifdef EXTENDED_FEATURE_MANAGER_TEST
+// -----------------------------------------------------------------------------
+// A new session is being created
+// Cancel the shutdown timer if it was running
+// -----------------------------------------------------------------------------
+//
+void CFeatMgrServer::AddSession()
+    {
+    FUNC_LOG
+    
+    ++iSessionCount;
+    iShutdown.Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// A session is being destroyed
+// Start the shutdown timer if it is the last session.
+// -----------------------------------------------------------------------------
+//
+void CFeatMgrServer::DropSession()
+    {
+    FUNC_LOG
+    
+    if (--iSessionCount==0)
+        {
+        if( !iShutdown.IsActive() )
+            {
+            iShutdown.Start();
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CShutDown
+// ---------------------------------------------------------------------------
+inline CShutdown::CShutdown()
+    :CTimer(-1)
+    {
+    CActiveScheduler::Add(this);
+    }
+    
+inline void CShutdown::ConstructL()
+    {
+    CTimer::ConstructL();
+    }
+
+inline void CShutdown::Start()
+    {
+    FUNC_LOG
+    After(KShutdownTimeout);
+    }
+
+void CShutdown::RunL()
+    {
+    FUNC_LOG
+    CActiveScheduler::Stop();
+    }
+
+#endif // EXTENDED_FEATURE_MANAGER_TEST
+    
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CFeatMgrServer::~CFeatMgrServer()
+    {
+    FUNC_LOG
+
+    // Close all open sessions
+	CFeatMgrSession* session=NULL;
+	iSessionIter.SetToFirst();
+	
+	while( (session = static_cast<CFeatMgrSession*>(iSessionIter++)) != NULL )
+	    {
+		delete session;
+	    }
+
+    // Delete plugin handlers    
+    if ( !iPluginsDeleted )
+        {
+        iPendingRequests = EFalse; // No need to serve pending requests
+        iFeaturesReady = ETrue; // No need to read files anymore
+        DeletePlugins();
+        } 
+    
+    delete iTimer;
+    iFs.Close();
+    iPluginList.Close();
+    
+    // De register Backup and Restore and cleanup memory
+    if( iBackupNotification ) 
+    	{
+		TFileName temp( iRegistry->GetFeaturesFilePathAndName() );
+    	iBackupNotification->DeregisterFile( temp );
+    	delete iBackupNotification;
+    	iBackupNotification = NULL;
+    	}
+    
+    delete iRegistry;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::NewSessionL
+// Creates a new CSession2
+// -----------------------------------------------------------------------------
+//
+CSession2* CFeatMgrServer::NewSessionL( const TVersion& aVersion,
+                                     const RMessage2& /*aMessage*/ ) const
+    {
+    FUNC_LOG
+    
+    if ( !User::QueryVersionSupported( TVersion( KServerVersionMajor, 
+                                                 KServerVersionMinor, 
+                                                 KServerVersionBuild ), 
+                                                 aVersion ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    
+    CSession2* session = CFeatMgrSession::NewL(*const_cast<CFeatMgrServer*>(this), *iRegistry );
+
+    return( session );
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::TimerFired
+// Handles timer firing. 
+// -----------------------------------------------------------------------------
+//
+void CFeatMgrServer::TimerFired()
+    {
+    FUNC_LOG
+
+    // Delete plugin handlers. Plugin handler deletes the plugin.    
+    if ( !iPluginsDeleted )
+        {
+        DeletePlugins();
+        } 
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::HandleFeatureChange()
+// -----------------------------------------------------------------------------
+//
+void CFeatMgrServer::HandleFeatureChange( TFeatureServerEntry& aFeature, TFeatureChangeType aType )
+    {
+    FUNC_LOG
+
+    CFeatMgrSession* session=NULL;
+	TDblQueIter<CSession2> local_iSessionIter = iSessionIter;
+	local_iSessionIter.SetToFirst();
+	    
+	while( (session = static_cast<CFeatMgrSession*>(local_iSessionIter++)) != NULL )
+	    {
+		session->ServiceNotifications( aFeature, aType );
+	    }
+    }
+
+// ---------------------------------------------------------------------------
+// CFeatMgrServer::ResetAndDestroyArray
+// ---------------------------------------------------------------------------
+// 
+static void ResetAndDestroyArray( TAny* aPtr )
+    {
+    RImplInfoPtrArray* array = static_cast< RImplInfoPtrArray* >( aPtr );
+    array->ResetAndDestroy();
+    array->Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::LoadPluginsL()
+// -----------------------------------------------------------------------------
+//
+TBool CFeatMgrServer::LoadPluginsL()
+    {
+    FUNC_LOG
+    
+    RImplInfoPtrArray implInfoArray;
+    TBool ret( EFalse );
+
+    // Use ECom to read information about existing interface implementations
+    _LIT8( KEmptyString, "" );
+    TEComResolverParams resolverParams;
+    resolverParams.SetDataType (KEmptyString);
+    resolverParams.SetWildcardMatch (ETrue);
+
+    TCleanupItem cleanupItem( ResetAndDestroyArray, &implInfoArray );
+    CleanupStack::PushL( cleanupItem );
+    
+    TIMESTAMP( "CFeatMgrServer::LoadPluginsL - ListImplementationsL start: " )
+    REComSession::ListImplementationsL( KFeatureInfoPluginInterfaceUid,
+#ifndef EXTENDED_FEATURE_MANAGER_TEST                                         
+                                        resolverParams,
+
+                                        KRomOnlyResolverUid, 
+#endif                                        
+                                        implInfoArray);
+    TIMESTAMP( "CFeatMgrServer::LoadPluginsL - ListImplementationsL end: " )
+    
+    // Check if any plugin was found. 
+    TInt count = implInfoArray.Count();
+    
+    if ( count > 0 )
+        {
+        
+        for(TInt i = 0; i < count; i ++)
+            {
+            CFeatMgrPluginHandler* pluginHandler = NULL;
+            TInt err( KErrNone );
+        
+            // Create handler
+            TRAP( err, pluginHandler = CFeatMgrPluginHandler::NewL( 
+                  implInfoArray[i]->ImplementationUid(), *this) );
+                
+            LOG_IF_ERROR1( err, "CFeatMgrServer::LoadPluginsL() - pluginHandler creation err %d", err );
+            
+            // Apply first request for plugin to process
+            if ( err == KErrNone )
+                {
+                TRAP( err, pluginHandler->SendCommandL( 
+                    FeatureInfoCommand::ELoadFeatureInfoCmdId ) );
+                }            
+            
+            // Panic if error sth else than not supported        
+            if ( err != KErrNone && err != KErrNotSupported )
+                {
+                ERROR_LOG2( "CFeatMgrServer::LoadPluginsL() - implementationUid: 0x%x, error: %d - going to panic",
+                                        implInfoArray[i]->ImplementationUid(), err );
+                User::Panic( KPanicCategory, EPanicLoadPluginError );                           
+                }
+            // If simple features are not supported by the plugin search for enhanced ones
+            else if ( err == KErrNotSupported )
+            	{
+            	// Reset error code
+            	err = KErrNone;
+                TRAP( err, pluginHandler->SendCommandL(
+                    FeatureInfoCommand::ELoadEnhancedFeatureInfoCmdId ) );
+
+                // Panic if error since in this case the plugin does not support any feature
+            	if ( err != KErrNone )
+	            	{
+	                ERROR_LOG2( "CFeatMgrServer::LoadPluginsL() - implementationUid: 0x%x, error: %d - going to panic",
+	                        implInfoArray[i]->ImplementationUid(), err );
+	                User::Panic( KPanicCategory, EPanicLoadPluginError );
+	            	}
+	            }
+            // If a simple or enhanced feature is supported by the plugin then append the plugin to the list
+            if ( err == KErrNone )
+            	{
+                INFO_LOG1( "CFeatMgrServer::LoadPluginsL() - Add info of implementationUid: 0x%x",
+                                        implInfoArray[i]->ImplementationUid() );
+            
+                // Add information of the plugin to the plugin list
+                SFeatMgrPluginInfo plugin;
+                plugin.iPluginHandler = pluginHandler;
+                // Set all plugins as not ready initially
+                plugin.iPluginReady = EFalse;
+
+                TInt err = iPluginList.Append(plugin);
+            
+                if ( err != KErrNone )
+                    {
+                    ERROR_LOG2( "CFeatMgrServer::LoadPluginsL() - Saving plugin info of implementationUid: 0x%x, err %d",
+                                                  implInfoArray[i]->ImplementationUid(), err );
+                    User::Leave( err );
+                    }
+                }
+            }
+        INFO_LOG1( "CFeatMgrServer::LoadPluginsL - interfaceUid.iUid == 0x%x, return plugins found",
+                           KFeatureInfoPluginInterfaceUid );
+        ret = ETrue;
+        }
+    
+    else
+        {
+        iPluginsReady = ETrue; // Plugins not found.
+        INFO_LOG1( "CFeatMgrServer::LoadPluginsL - interfaceUid.iUid == 0x%x, return plugins not found",
+                           KFeatureInfoPluginInterfaceUid );
+        ret = EFalse;
+        }
+    
+    CleanupStack::PopAndDestroy(&implInfoArray);
+    
+    return ret;
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::PluginsReady()
+// -----------------------------------------------------------------------------
+
+TBool CFeatMgrServer::PluginsReady() const
+    {
+    FUNC_LOG
+    return(iPluginsReady);
+   	}
+   	
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::ServicePendingRequests()
+// -----------------------------------------------------------------------------
+
+void CFeatMgrServer::ServicePendingRequests()
+    {
+    FUNC_LOG
+    
+    CFeatMgrSession* session=NULL;
+	iSessionIter.SetToFirst();
+	    
+	while( (session = static_cast<CFeatMgrSession*>(iSessionIter++)) != NULL )
+	    {
+		TRAPD( err, session->ServicePendingRequestsL() );
+        LOG_IF_ERROR1( err, "CFeatMgrServer::ServicePendingRequests - err %d", err );
+	    }
+   	
+   	iPendingRequests = EFalse;
+   	}
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::DeletePlugins()
+// -----------------------------------------------------------------------------
+
+void CFeatMgrServer::DeletePlugins()
+    {
+    FUNC_LOG
+    
+    // Set iPluginsReady to ETrue because plugins will be deleted.
+    iPluginsReady = ETrue;
+    TInt err( KErrNone );
+
+    // Load runtimefeatures.txt if not loaded yet.
+    if ( !iFeaturesReady )
+        { 
+        TRAP( err, iRegistry->ReadRuntimeFeaturesL( iFeaturesReady ) );
+        
+        LOG_IF_ERROR1( err, "CFeatMgrServer::DeletePlugins() - ReadRuntimeFeaturesL err %d", err ); 
+        }
+    
+    // Service pending requests before deleting plugins if not serviced yet.
+    if ( iPendingRequests )
+        {
+        ServicePendingRequests();
+        }
+          
+    // Delete plugin handlers
+    TInt count = iPluginList.Count();
+
+    for ( TInt i = 0 ; i < count; i++ )
+        {
+        delete iPluginList[i].iPluginHandler;
+        iPluginList[i].iPluginHandler = NULL;
+        }
+
+    // Reset list of plugins
+    iPluginList.Reset();
+        
+    // Signal final closure of ecom session
+	REComSession::FinalClose();
+	    
+	// All plugin handlers deleted
+	iPluginsDeleted = ETrue;
+	}
+    
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::FeatureInfoL()
+// -----------------------------------------------------------------------------
+
+void CFeatMgrServer::FeatureInfoL( RArray<FeatureInfoCommand::TFeature>& aFeatureList, 
+        CFeatMgrPluginHandler* aPluginHandler )
+    {
+    FUNC_LOG
+     
+    // Save feature info received from the plugin
+    TInt pluginCount = iPluginList.Count();
+
+    for ( TInt i = 0; i < pluginCount; i ++ )
+        {
+        if ( iPluginList[i].iPluginHandler == aPluginHandler )
+            {
+            iRegistry->MergePluginFeatures( aFeatureList );
+            // Send command to load enhanced feature info
+            TRAPD( err, iPluginList[i].iPluginHandler->SendCommandL( 
+                FeatureInfoCommand::ELoadEnhancedFeatureInfoCmdId ) );
+            // Panic if error sth else than not supported
+            if ( err != KErrNone && err != KErrNotSupported )
+                {
+                ERROR_LOG1( "CFeatMgrServer::FeatureInfoL() - panicing due error %d", err );
+                User::Panic( KPanicCategory, EPanicLoadPluginError );
+                }
+            // At this point we have simple feature supported by the plugin.
+            // If no enhanced feature is supported, but a simple one is, then
+            // the plugin is ready to be used. Otherwise continue to add the
+            // enhanced features.
+            else if( err == KErrNotSupported )
+            	{
+            	iPluginList[i].iPluginReady = ETrue;
+                }
+            }
+        else
+            {
+            INFO_LOG( "CFeatMgrServer::FeatureInfo - unknown plugin handler") ;
+            }
+        }   
+
+    CheckPluginsReadyL();
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::FeatureInfoL()
+// -----------------------------------------------------------------------------
+
+void CFeatMgrServer::FeatureInfoL( RFeatureArray& aFeatureList, 
+        CFeatMgrPluginHandler* aPluginHandler )
+    {
+    FUNC_LOG
+     
+    // Save feature info received from the plugin
+    TInt pluginCount = iPluginList.Count();
+
+    for ( TInt i = 0; i < pluginCount; i ++ )
+        {
+        if ( iPluginList[i].iPluginHandler == aPluginHandler )
+            {
+            iRegistry->MergePluginFeatures( aFeatureList );
+            // Send another command if something left to process
+            iPluginList[i].iPluginReady = ETrue;
+            }
+        else
+            {
+            INFO_LOG( "CFeatMgrServer::FeatureInfo - unknown plugin handler") ;
+            }
+        }   
+
+    CheckPluginsReadyL();
+    }
+
+// -----------------------------------------------------------------------------
+// CFeatMgrServer::CheckPluginsReadyL()
+// -----------------------------------------------------------------------------
+
+void CFeatMgrServer::CheckPluginsReadyL()
+    {
+    FUNC_LOG
+
+    // If all plugins has responsed iPluginsReady is ETrue
+    // else iPluginsReady is EFalse;
+    TInt pluginCount = iPluginList.Count();
+    
+    for ( TInt i = 0; i < pluginCount; i ++ )
+        {
+        if ( iPluginList[i].iPluginReady )
+            {
+            iPluginsReady = ETrue;
+            }
+        else
+            {   
+            iPluginsReady = EFalse;
+            break;
+            }
+        }
+    
+    // If plugins ready, read runtime features and call ServicePendingRequests of sessions.
+    if ( iPluginsReady )
+        {
+        // Load runtimefeatures.txt
+        if ( !iFeaturesReady )
+            {
+            iRegistry->ReadRuntimeFeaturesL( iFeaturesReady );
+            }
+
+        if ( iPendingRequests )
+            {
+            ServicePendingRequests();    
+            }
+        }      
+    }
+    
+/**
+ * Implementation of the pure virtual function.
+ */
+void CFeatMgrServer::HandleBackupOperationEventL( const TBackupOperationAttributes& /* aBackupOperationAttributes */ )
+	{
+	return;
+	}
+
+/**
+ * There is a flag state variable being passed into Feature Manager as type MBackupObserver::TFileLockFlags.
+ * Only certain combinations of these flags are valid for Feature Manager and if the combination is 
+ * not valid, then because there is no way of returning an error it will just set the internal state 
+ * machine into an "error" state.
+ * Given our current state and our goto state (i.e. where we are at the moment and where we want to goto)
+ * the state machine checks that this is a valid path in our state machine and then perform the correct 
+ * operations to get us to the next valid state. It also calls the correct Feature manager functions to 
+ * accomplish this operation.
+ */
+void CFeatMgrServer::ChangeFileLockL( const TDesC& /* aFileName */, TFileLockFlags aFlags )
+	{
+	// There is only one file we are concerned with, so
+	// don't check the filename matches
+	// Default TOperationType type to ENone (we are ignoring this value)
+	TBackupOperationAttributes attribs( aFlags, ENone );
+	iBurState.BUROperationL( attribs );
+
+	return;
+	}
+
+
+/**
+ * Generic return function, to return the state of the machine back to normal.
+ * This can only occur from certain states.
+ */
+BURStatus CFeatMgrServer::Goto_NormalState( BURStatus /* aCurrent */  )
+	{
+	return EFeatMgrBURState_None;   // all roads lead to normal state
+	}
+
+/**
+ * This function handles error recovery from an invalid state. It will return the feature 
+ * maneger back to normal, in both it's internal state machine state, and it's internal 
+ * variables.
+ */
+BURStatus CFeatMgrServer::Goto_ErrorState( BURStatus aCurrent  )
+	{
+	BURStatus aNewState = EFeatMgrBURState_None;   // fail safe: all roads lead to normal state
+	TInt err( KErrNone );
+	
+	switch( aCurrent )
+		{
+		case( EFeatMgrBURState_BackupStarted ) :
+			iPluginsReady = ETrue;
+			ServicePendingRequests();
+			break;
+		case( EFeatMgrBURState_RestoreStarted ) :
+		    iPluginsReady    = EFalse;
+		    iPluginsDeleted  = EFalse;
+		    iPendingRequests = ETrue;
+		    iFeaturesReady   = EFalse;
+			// re-read the new features;
+			ClearFeatures();
+			TRAP( err, LoadFeaturesL()  );
+			// Stop queuing
+			iPluginsReady = ETrue;
+			// commit the pending change requests
+			ServicePendingRequests();
+			break;
+		case( EFeatMgrBURState_BackupEnded ) :
+		case( EFeatMgrBURState_RestoreEnded ) :
+			break;
+		default :
+			break;
+		}
+	
+	aNewState = EFeatMgrBURState_Error;  // state++
+	return aNewState;
+	}
+
+BURStatus CFeatMgrServer::Goto_StartBackupState( BURStatus /* aCurrent */ )
+	{
+	BURStatus aNewState = EFeatMgrBURState_BackupStarted;  // state++
+	iPluginsReady = EFalse;
+	return aNewState;
+	}
+
+BURStatus CFeatMgrServer::Goto_EndBackupState( BURStatus /* aCurrent */  )
+	{
+	BURStatus aNewState = EFeatMgrBURState_BackupEnded;   // state++
+	
+	iPluginsReady = ETrue;
+	ServicePendingRequests();
+	// no error from ServicePendingRequests() is possible
+	
+	return aNewState;
+	}
+
+BURStatus CFeatMgrServer::Goto_StartRestoreState( BURStatus /* aCurrent */  )
+	{
+	// remarkably like Goto_StartBackupState
+	BURStatus aNewState = EFeatMgrBURState_RestoreStarted;  // state++
+	iPluginsReady = EFalse;
+	return aNewState;
+	}
+
+BURStatus CFeatMgrServer::Goto_EndRestoreState( BURStatus /* aCurrent */  )
+	{
+	BURStatus aNewState = EFeatMgrBURState_Error;   // fail safe
+	TInt err( KErrNone );
+	
+    iPluginsReady    = EFalse;
+    iPluginsDeleted  = EFalse;
+    iPendingRequests = ETrue;
+    iFeaturesReady   = EFalse;
+
+	// re-read the new features
+    // Only call the next function if the previous one was
+    // successfully completed.
+	ClearFeatures();
+	TRAP( err, LoadFeaturesL()  );
+	if( err == KErrNone ) 
+		{
+		TRAP( err, HandleRestoredNotificationsL() );
+		}
+
+	if( err != KErrNone )
+		{
+		// error condition
+		aNewState = EFeatMgrBURState_Error;
+		}
+	else
+		{
+		// Stop queuing
+		iPluginsReady = ETrue;
+		
+		// commit the pending change requests
+		ServicePendingRequests();
+		
+		// Change state machine
+		aNewState = EFeatMgrBURState_RestoreEnded;
+		}
+	
+	return aNewState;
+	}
+
+/**
+ * This function will load features from files and plugins 
+ */
+void CFeatMgrServer::LoadFeaturesL( void )
+	{
+    // Load ROM (Z)
+	TRAPD( err, iRegistry->ReadFeatureFilesL() );
+	if( KErrNotFound == err)
+		{
+		ERROR_LOG( "CFeatMgrServer::ConstructL() & CallReadFeatureFilesL() - no feature files found in ROM - going to panic");
+	    User::Panic( KPanicCategory, EPanicNoFeatureFiles );
+		}
+	else
+		{
+		User::LeaveIfError(err);
+		}
+
+    // Load RAM (C)
+	// List and load plugins and feature info.
+	TBool found = LoadPluginsL();
+	
+	if( found )
+	    {
+	    // Timer for deleting plugins and for comparing feature lists.
+	    iTimer = CFeatMgrTimer::NewL( *this );
+	    }
+	else
+	    {
+	    TRAPD( err, iRegistry->ReadRuntimeFeaturesL( iFeaturesReady ) );
+		if( KErrNotFound == err)
+			{
+		    User::Panic( KPanicCategory, EPanicNoFeatureFiles );
+			}
+		else
+			{
+			User::LeaveIfError(err);
+			}
+	    }
+
+	return;
+}
+
+
+/**
+ * Discover which features have changes wrt the restore operation
+ */
+void CFeatMgrServer::HandleRestoredNotificationsL( void )
+	{
+	iRegistry->HandleRestoredFeatureNotificationsL();
+	
+	return;
+	}
+
+/**
+ * This function will clear features from RAM
+ */
+void CFeatMgrServer::ClearFeatures( void )
+	{
+	// Delete plugin handlers    
+    if ( !iPluginsDeleted )
+        {
+        // Delete plugin handlers
+        TInt count = iPluginList.Count();
+        for ( TInt i = 0 ; i < count; i++ )
+            {
+            delete iPluginList[i].iPluginHandler;
+            iPluginList[i].iPluginHandler = NULL;
+            }
+
+        // Reset list of plugins
+        iPluginList.Reset();
+        iPluginList.Close();        
+    	    
+    	// All plugin handlers deleted
+    	iPluginsDeleted = EFalse;
+        } 
+
+    if( NULL != iRegistry )
+    	{
+        iRegistry->ResetFeatures();
+        }
+
+    return;
+}
+
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// Function that starts the FeatMgrServer.
+// -----------------------------------------------------------------------------
+//
+static void RunServerL()
+    {
+    FUNC_LOG
+
+    // Naming the server thread after the startup helps to debug panics
+    User::LeaveIfError( User::RenameProcess( KServerProcessName ) );
+    
+    User::LeaveIfError( User::RenameThread( KServerProcessName ) );
+     
+    // Create and install the active scheduler we need
+    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+    CleanupStack::PushL( scheduler );
+    
+    CActiveScheduler::Install( scheduler );
+    
+    // Now we are ready to instantiate the actual CServer2 instance
+    CFeatMgrServer* server = CFeatMgrServer::NewLC( KServerCActivePriority );
+
+	// Initialisation complete, now signal the client
+	RProcess::Rendezvous(KErrNone);
+
+    INFO_LOG( "RunServerL() - Starting scheduler..." );
+
+	// Ready to run
+	CActiveScheduler::Start();
+
+    INFO_LOG( "RunServerL() - Scheduler stopped" );
+
+	// Cleanup the server and scheduler
+	CleanupStack::PopAndDestroy( server );
+	CleanupStack::PopAndDestroy( scheduler );
+    }
+
+// -----------------------------------------------------------------------------
+// Main function
+// -----------------------------------------------------------------------------
+//
+TInt E32Main()
+    {
+    FUNC_LOG
+
+	__UHEAP_MARK;
+
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	TInt ret = KErrNoMemory;
+
+	if ( cleanup )
+		{
+		TRAP( ret, RunServerL() );
+		delete cleanup;
+		}
+
+	__UHEAP_MARKEND;
+
+	return ret;
+    }
+
+//  End of File