lowlevellibsandfws/pluginfw/Framework/frame/EComServer.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 17 Sep 2010 08:38:54 +0300
changeset 63 a117ad66e027
parent 0 e4d67989cc36
permissions -rw-r--r--
Revision: 201037 Kit: 201037

// Copyright (c) 1997-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:
// The Definition of the CEComServer singleton class which
// instantiates an instance of the requested ECom Interface Implementation.
// 
//

/**
 @internalComponent
 @file
*/

#ifndef __ECOMSERVER_H__
#define __ECOMSERVER_H__

#include <f32file.h>
#include "clientrequest.h"
#include <ecom/ecom.h>
#include <ecom/ecomerrorcodes.h>
#include <ecom/ecomresolverparams.h>
#include <ecom/implementationinformation.h>
#include <ecom/implementationproxy.h>
#include "RegistrarObserver.h"
#include "EComPerformance.h"
#include <babitflags.h>
#include "callback.h"

// Forward declarations
class CRegistryData;
class CRegistrar;
class CResolver;
class CDefaultResolver;
class CRomOnlyResolver;
class TEComResolverParams;
class CServerStartupMgr;
class CRegistryResolveTransaction;
class CCustomResolverCache;

//#define _TRANSIENT_SERVER

#ifdef _TRANSIENT_SERVER
/**
Specifies that the server should shut down after a specified time
If not defined then the server never shuts down
@internalComponent
*/
const TInt KEComShutdownDelay = 0x500000;	// approx 0.5 seconds
#endif


/**
	@internalComponent
	@since 7.0
	A shutdown control object that activates the 
	destruction of the ECom server when its RunL
	fires, by stopping the local scheduler.
 */

class CShutdown : public CTimer
	{
public:
/**
	@internalComponent
	Intended Usage	: Default c'tor	
	Error Condition	: None	
	@since			7.0
	@pre 			None
	@post			CShutdown is fully constructed.
 */
	
	inline CShutdown();

/**
	Intended Usage	: Standardised 2nd, (Initialisation) phase of two 
					phase construction.
	Error Condition	: None	
	@leave			KErrNoMemory
	@since			7.0
	@pre 			CShutdown is fully constructed.
	@post			CShutdown is fully initialised.
 */
	
	inline void ConstructL();

/**
	Intended Usage	: Activate the shutdown timeout.
	Error Condition	: None	
	@since			7.0
	@pre 			CShutdown is fully constructed.
	@post			CShutdown is active pending timeout.
 */
	
	inline void Start();

private:
/**
	Intended Usage	: The timeout has expired, so begin server destruction.
	Error Condition	: None	
	@since			7.0
	@pre 			CShutdown is fully constructed.
	@post			the local CActiveScheduler::Stop() has been called.
 */
	
	void RunL();
	};


/**
	@internalComponent
	@since 7.0
	A concrete implementation which supplies instantiation & 
	destruction of a class via the ECom framework.
 */

class CEComServer : private CServer2, private MRegistrarObserver
	{
	public:
/**
	Intended Usage	: Standardised safe construction which 
					leaves the returned object on the cleanup stack.
	Error Condition	: Cannot fully construct because of 
					memory limitations.	
	@leave  		KErrNoMemory
	@leave  		@see RFs, CRegistryData, CRegistrar, CDefaultResolver
	@leave  		@see CShutdownTimer & CServer::StartL
	@since			7.0
	@return			CEComServer* a pointer to the new class
	@pre 			None
	@post			CEComServer is fully constructed, initialised,
					and remains upon the cleanup stack.
*/
	
	static CEComServer* NewLC();

/**
	Intended Usage	: d'tor
	Error Condition	: None	
	@since			7.0
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer is destroyed.
 */
	~CEComServer();

/**
	Intended Usage	: Reads the EComSrvr.ini file to determine if
					  ECOM should be SSA or not.
	@param			aFs A reference to a connected file server session.
	@pre 			CEComServer must have been fully constructed.
	*/
	TBool IsSSA(RFs& aFs);

/**
	Intended Usage	: Retrieve a list of all the implementations which 
					satisfy the specified interface.
	Error Condition	: Lack of memory.	
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aAdditionalParameters A descriptor specifying any additional
					implementation characteristics to be fulfilled.
	@param			aExtendedInterfaces Identifies a set of zero or more extended interfaces to match. 
					Must match all extended interfaces for a match to occur.
	@param			aMessage Client's request					
	@return			RImplInfoArray* A pointer to the array of CImplementationInformation pointers. 
		            Ownership of the created array is returned to the caller,
					who must take the responsibility of destroying it. However, the caller must
					not destroy the list's contents as it is not owned by the list.
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has not changed, and RImplInfoArray* contains the list
					of CImplementationInformations regigistered for the interface.		
 */
	
	RImplInfoArray* ListImplementationsL(TUid aInterfaceUid, 
										 const TEComResolverParams& aAdditionalParameters,
										 const RExtendedInterfacesArray& aExtendedInterfaces,
										 const TClientRequest& aMessage);

/**
	Intended Usage	: Retrieve a list of all the implementations which 
					satisfy the specified interface.
	Error Condition	: Lack of memory.	
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aExtendedInterfaces Identifies a set of zero or more extended interfaces to match. 
					Must match all extended interfaces for a match to occur.
	@param			aMessage Client's request					
	@return			RImplInfoArray* A pointer to the array of CImplementationInformation pointers. 
	                Ownership of the created array is returned to the caller,
					who must take the responsibility of destroying it. However, the caller must
					not destroy the list's contents as it is not owned by the list.
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has not changed, and RImplInfoArray* contains the list
					of CImplementationInformations regigistered for the interface.			
 */
	
	RImplInfoArray* ListImplementationsL(TUid aInterfaceUid, 
										 const RExtendedInterfacesArray& aExtendedInterfaces, 
										 const TClientRequest& aMessage);

/**
	Intended Usage	: Retrieve a list of all the implementations which 
					satisfy the specified interface.
	Error Condition	: Lack of memory.	
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aAdditionalParameters A descriptor specifying any additional
					implementation characteristics to be fulfilled.
	@param			aResolverUid The CResolver implementation to use.
	@param			aExtendedInterfaces Identifies a set of zero or more extended interfaces to match. 
					Must match all extended interfaces for a match to occur.
	@param			aMessage Client's request										
	@return			RImplInfoArray* A pointer to the array of CImplementationInformation pointers.
					Ownership of the created array is returned to the caller,
					who must take the responsibility of destroying it. However, the caller must
					not destroy the list's contents as it is not owned by the list.
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has not changed, and RImplInfoArray* contains the list
					of CImplementationInformations regigistered for the interface.
 */
	
	RImplInfoArray* ListImplementationsL(TUid aInterfaceUid, 
										 const TEComResolverParams& aAdditionalParameters, 
										 TUid aResolverUid,
										 const RExtendedInterfacesArray& aExtendedInterfaces,
										 const TClientRequest& aMessage);
/**
	Intended Usage	: Retrieve a list of all the implementations which 
					satisfy the specified interface.
	Error Condition	: Lack of memory.	
	@leave			KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aResolverUid The CResolver implementation to use.
	@param			aExtendedInterfaces Identifies a set of zero or more extended interfaces to match. 
					Must match all extended interfaces for a match to occur.
	@param			aMessage Client's request					
	@return			RPointerArray<TUid>* A pointer to the array of class identification
					data.
					Ownership of the created array is returned to the caller,
					who must take the responsibility of destroying it. However, the caller must
					not destroy the list's contents as it is not owned by the list.	
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has not changed, and RPointerArray<TUid>* contains the list
					of Implementations for the interface.		
 */
	
	RImplInfoArray* ListImplementationsL(TUid aInterfaceUid, 
										 TUid aResolverUid,
										 const RExtendedInterfacesArray& aExtendedInterfaces,
										 const TClientRequest& aMessage);

/**
	Intended Usage	:Instantiate an interface implementation to satisfy the 
					specified interface. 
	Error Condition	: Lack of memory, or not connected.	
	@leave			KErrNoMemory
	@leave			KErrNotConnected
	@since			7.0
	@param			aImplementationUid A UID specifying the required interface implementation.
	@param			aDllInfo containing the Dll info to be loaded on the client side
	@param			aInstanceKey A 32 bit identifer returned by ECom to
					identify this instance to the framework.
	@param			aClientRequest client's request
	@pre 			CEComServer must have been fully constructed.
	@post			The requested interface implementation is identified,
					and the instantiation method pointer is returned.
 */
	
	void GetResolvedDllInfoL(	const TUid aImplementationUid,
								TEntry& aDllInfo,
								TUid& aInstanceKey,
								const TClientRequest& aClientRequest);


/**
	Intended Usage	:Instantiate an interface implementation to satisfy the 
					specified interface. 
	Error Condition	: Lack of memory	
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aAdditionalParameters A descriptor specifying any additional
					implementation characteristics to be fulfilled.
	@param			aExtendedInterfaces Identifies a set of zero or more extended interfaces to match.
					Must match all extended interfaces for a match to occur.					
	@param			aDllInfo containing the Dll info to be loaded on the client side
	@param			aInstanceKey A 32 bit identifer returned by ECom to
					identify this instance to the framework.
	@param			aClientRequest client's request
	@pre 			CEComServer must have been fully constructed.
	@post			The requested interface implementation is identified,
					and the instantiation method pointer is returned.
 */
	
	void GetResolvedDllInfoL(	const TUid aInterfaceUid,
								const TEComResolverParams& aAdditionalParameters,
								const RExtendedInterfacesArray& aExtendedInterfaces,
								TEntry& aDllInfo,
								TUid& aInstanceKey,
								const TClientRequest& aClientRequest);

/**
	Intended Usage	:Instantiate an interface implementation to satisfy the 
					specified interface. 
					Overload with a client provided CResolver.
	Error Condition	: Lack of memory	
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aAdditionalParameters A descriptor specifying any additional
					implementation characteristics to be fulfilled.
	@param			aResolver A UID specifying the implementation of the CResolver interface
					with client defined behaviour to use for resolution.
	@param			aExtendedInterfaces Identifies a set of zero or more extended interfaces to match.
					Must match all extended interfaces for a match to occur.					
	@param			aDllInfo containing the Dll info to be loaded on the client side
	@param			aInstanceKey A 32 bit identifer returned by ECom to
					identify this instance to the framework.
	@param			aClientRequest client's request
	@pre 			CEComServer must have been fully constructed.
	@post			The requested interface implementation is identified,
					and the instantiation method pointer is returned.
 */
	
	void GetResolvedDllInfoL(   const TUid aInterfaceUid, 
								const TEComResolverParams& aAdditionalParameters,
								const TUid aResolverUid,
								const RExtendedInterfacesArray& aExtendedInterfaces,
								TEntry& aDllInfo,
								TUid& aInstanceKey,
								const TClientRequest& aClientRequest);
	
/**
	Get implementation info for one implementation, and return to client
	@param			aImplementationUid A UID specifying the required implementation.
	@param			aImplInfo Return value, implementation info for client. If the call succeeds,
					it will point to the found implementation information in registrydata. The function 
					does not return ownership of the pointer, so the caller must not destroy it.
	@param			aClientRequest client's request
 */							
	void GetImplementationInformationL(const TUid& aImplementationUid,
									   CImplementationInformation*& aImplInfo,
									   const TClientRequest& aClientRequest);

#ifdef __ECOM_SERVER_TESTABILITY__
/**
	This method is provided for testability. It allows the user to 
	simulate the domain manager behaviour. If the testing compile
	time flag __ECOM_SERVER_TESTABILITY__ is not defined the method
	is not accessible. If the flag is defined then it is responsible
	for setting the startup state. After the state is changed
	the ProcessCurrentStartupStateL() method should be called for 
	correct simulation of domain manager behaviour.
	@param aState the state to change to
*/
	void ChangeStartupStateL(TInt aState) const;
		
/**
	This method is provided for testability. It allows the user to 
	simulate the domain manager behaviour. If the testing compile
	time flag __ECOM_SERVER_TESTABILITY__ is not defined the method
	is not accessible. If the flag is defined then it is responsible
	for processing the startup state. ChangeStartupState() method 
	should be called prior to calling this method.
	@leave System-wide error codes, including KErrNoMemory.
*/
	void ProcessCurrentStartupStateL() const;
	
/**
	This method is provided for testability. It allows the user to 
	simulate the domain manager behaviour. If the testing compile
	time flag __ECOM_SERVER_TESTABILITY__ is not defined the method
	is not accessible. It is an accessor
	to test the current state of the ServerStartupManager.
	@return The current startup state of the CServerStartupManager.
*/
	TInt GetCurrentStartupState() const;
#endif //__ECOM_SERVER_TESTABILITY__

#ifdef __ECOM_SERVER_PERFORMANCE__
/**
	This method is provided for performance testability. If the testing 
	compile	time flag __ECOM_SERVER_PERFORMANCE__ is not defined the method
	is not accessible. It is an accessor to get the plugins counts discovered
	during the startup of EComServer.
	@param aType the type of counts to read
	@param aCounts the count readings
*/
	void GetRegistryCountsL(TInt aType, RegistryCounts::TRegistryCounts& aCounts) const;
	
#endif //__ECOM_SERVER_PERFORMANCE__

/**
	Intended Usage	: (Server Session management) Add a new session connection for a client.	
	Error Condition	: None.
	@since			7.0
	@pre 			CEComServer must have been fully constructed.
	@post			The new CEComServerSession to handle service provision for a new 
					ECom client has been recorded.
					If the server was preparing to shutdown, that shutdown is cancelled
 */
	
	void AddSession();

/**
	Intended Usage	: (Server Session management) Destroy a session connection with a client.	
	Error Condition	: None.
	@since			7.0
	@pre 			CEComServer must have been fully constructed.
	@post			The appropriate CEComServerSession has been destroyed and 
					the ECom client has been disconnected from this server.
 */
	
	void DropSession();

/**
	Intended Usage	: The overloaded method from the MRegistrarObserver class
					  Used for firing notifications to the client sessions that
					  the underlying registry data has changed.
	Error Condition	: None	
	@since			7.0
	@pre 			CEComServer must have been fully constructed.
	@post			The CEComServer has notified all its client sessions
					registered for notifications that the data changed. 
 */
	
	void Notification(TInt aNotificationCode);

/**
	Intended Usage	: Indicates whether the registry index is currently valid.  The 
					index will not be valid if discoveries are currently taking place.
					If the index is not currently valid then calls to 
					ListImplementationsL() cannot be serviced.
	Error Condition	: None.
	@return			ETrue if the index is currently valid, EFalse otherwise.
	@since			7.0
	@pre 			CEComServer is fully constructed
 */
	
	TBool RegistryIndexValid() const;

	// Callback function to be invoked by CDiscoverer and CRegistryData
	static TInt NotifyEvents(TAny* aObj, TInt aEvent, TAny* aData);

private:
/**
	@internalComponent
	Intended Usage	: Default c'tor	
	Error Condition	: None	
	@since			7.0
	@pre 			None
	@post			CEComServer is fully constructed
 */
	
	CEComServer();

/**
	Intended Usage	: Standardised 2nd, (Initialisation) phase of two 
					phase construction.
	Error Condition	: None	
	@leave  		KErrNoMemory
	@since			7.0
	@return			void 
	@pre 			CEComServer is fully constructed.
	@post			CEComServer is fully initialised.
 */
	
	void ConstructL();

/**
	Intended Usage	: Helper method to retrieve a list of all the 
					implementations which satisfy the specified interface. 
					Overload with a provided CResolver*.
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aAdditionalParameters A descriptor specifying any additional
					implementation characteristics to be fulfilled.
	@param			aResolver A CResolver with client defined behaviour.
	@return			RPointerArray<TUid>* A pointer to the array of class identification
					data. Ownership of the created array is returned to the caller,
					who must take the responsibility of destroying it. However, the caller must
					not destroy the list's contents as it is not owned by the list.
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has not changed, and RPointerArray<TUid>* contains the list
					of Implementations for the interface.			
 */
	
	RImplInfoArray* ListImplementationsL(TUid aInterfaceUid, 
										 const TEComResolverParams& aAdditionalParameters, 
										 CResolver* aResolver) const;
/**
	Intended Usage	: Helper method to retrieve a list of all the 
					implementations which satisfy the specified interface. 
					Overload with a provided CResolver*.
	@leave  		KErrNoMemory
	@since			7.0
	@param			aInterfaceUid A UID specifying the required interface.
	@param			aResolver A CResolver with client defined behaviour.
	@return			A pointer to the array of class identification data. 
                 	Ownership of the created array is returned to the caller,
					who must take the responsibility of destroying it. However, the caller must
					not destroy the list's contents as it is not owned by the list.
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has not changed, and RPointerArray<TUid>* contains the list
					of Implementations for the interface.		
 */
	
	RImplInfoArray* ListImplementationsL(TUid aInterfaceUid, 
										 CResolver* aResolver) const;

/**
	Intended Usage	: Creates a new CEComServerSession to handle client
					service requests.
	@leave			KErrNoMemory
	@leave			@see CSharableSession
	@pre 			CEComServer must have been fully constructed.
	@post			CEComServer has created a new CEComServerSession.
 */
	
	CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;

/**
	Intended Usage	: Intercept the panic caused by a RunL leave,
					to restore the CEComServer object to a sensible state.
					(called by the Active Scheduler immediately before the Panic).
	Error Condition	: None.
	@since			7.0
	@return			TInt KErrNone if cleanup successful, otherwise return aError
	@pre 			CEComServer is fully constructed.
	@post			CEComServer has been restored to a sensible state.
 */
	
	TInt RunError(TInt aError);

/**
	Intended Usage: Creates custom resolver object with aResolverUid UID.
	The method leaves custom resolver onto the cleanup stack.
	@param aResolverUid Custom resolver UID.
	@param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
	@return A pointer to the created CResolver object.
	@leave System-wide error codes, including KErrNoMemory.
*/
	CResolver* CreateCustomResolverLC(TUid aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction);

/**
	Intended Usage: Creates resolver object with aResolverUid UID.
	The method leaves resolver onto the cleanup stack.
	@param aResolverUid Resolver UID.
	@param			aRegistryResolveTransaction A pointer to Registry resolve transaction object
	@return A pointer to the created CResolver object.
	@leave System-wide error codes, including KErrNoMemory.
*/
	CResolver* CreateResolverLC(const TUid& aResolverUid,CRegistryResolveTransaction* aRegistryResolveTransaction);

	void NotifyUpgrade(const TUid aImplementationUid);
	void NotifySWIEvent(TAny* aData);
	void NotifyBUREvent(TAny* aData);
	void UpdateSpecialEvents(TUint32 aBit, TCallBackState aState);
	TBool IsCachable(TBool aEntryIsOnRWDrive);

// Attributes
private:
	/** Singleton connection to the file server */
	RFs iFs;
	/** Singleton registry information handler */
	
	CRegistryData*	iRegistryData;
	
	/** Registry resolve transaction object */	
	CRegistryResolveTransaction* iRegistryResolveTransaction;
	
	/** Singleton Registrar to handle the interface registration */
	
	CRegistrar* iRegistrar;

	/** The count of the number of sessions open upon this server */
	
	TInt iSessionCount;
	/** The timer controlling the server shutdown process */
	
	CShutdown iShutdown;
	
	/** CServerStartupMgr object which interacts with Domain Manager*/
	CServerStartupMgr* iServerStartupMgr;
	
	/** Library which is used to load a non-default resolver when required */
	RLibrary iResolverLibrary;
	
	/** cache of recently used custom resolvers. */
	CCustomResolverCache* iResolverCache;

	/** Keep track of special system events such as BUR / SWI in progress */
	TBitFlags32 iSpecialEvents;

	// And the Test bed state accessor
	friend class TEComServer_StateAccessor;
	};

// Inline implementations for CShutdown
// Set the priority for shutdown as marginally less than normal
// operation.
const TInt KEComShutdownPriority = CActive::EPriorityStandard - 1;
inline CShutdown::CShutdown()
:CTimer(KEComShutdownPriority)
	{ 
	CActiveScheduler::Add(this); 
	}

inline void CShutdown::ConstructL()
	{ 
	CTimer::ConstructL();
	}

inline void CShutdown::Start()
	{
// Kick off the shutdown timer if this is a debug run
// Otherwise NEVER close.
#ifdef _TRANSIENT_SERVER
	After(KEComShutdownDelay);
#endif
	}

#endif // __ECOMSERVER_H__