messagingfw/sendas/server/src/csendasserver.cpp
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "csendasserver.h"
       
    17 
       
    18 #include <ecom/ecom.h>
       
    19 #include <barsc.h> 
       
    20 #include <barsread.h>
       
    21 
       
    22 #include "csendassession.h"
       
    23 #include "csendasservertimer.h"
       
    24 #include "sendasserverdefs.h"
       
    25 #include "sendasservername.h"
       
    26 #include "csendasactivecontainer.h"
       
    27 #include "csendasmtmmanager.h"
       
    28 
       
    29 // time the server will stay alive after the last session closes.
       
    30 const TInt KSendAsServerCloseTime 		= 2000000;  //  2 seconds
       
    31 
       
    32 // time the server will stay alive between starting and the first connect
       
    33 // operation arriving.
       
    34 const TInt KSendAsServerInitCloseTime 	= 10000000; // 10 seconds
       
    35 
       
    36 // location of the server resource file and resource struct version number
       
    37 _LIT(KSendAsServerResourceFile,"Z:\\resource\\messaging\\sendasserver.rsc");
       
    38 const TInt KResVersion = 0x00000001;
       
    39 
       
    40 /** Factory function to create a new instance of the SendAs server.
       
    41 
       
    42 @return
       
    43 A new CSendAsServer object.  This object is left on the cleanup stack.
       
    44 */
       
    45 CSendAsServer* CSendAsServer::NewLC()
       
    46 	{
       
    47 	CSendAsServer* self = new (ELeave) CSendAsServer;
       
    48 	CleanupStack::PushL(self);
       
    49 	self->ConstructL();
       
    50 	return self;
       
    51 	}
       
    52 	
       
    53 /** Second-stage constructor.
       
    54 
       
    55 Here the server allocates the 'object container index' object that is used to
       
    56 keep track of the sessions.
       
    57 */
       
    58 void CSendAsServer::ConstructL()
       
    59 	{
       
    60 	iMsvSession = CMsvSession::OpenSyncL(*this);
       
    61 	iContainerIndex = CObjectConIx::NewL();
       
    62 	
       
    63 	iMtmManager = CSendAsMtmManager::NewL(*this);
       
    64 
       
    65 	// read UIDs for edit tools and confirmation notifier from file
       
    66 	ReadResourceFileL();	
       
    67 
       
    68 	// configure the close timer to shut us down if there are no sessions
       
    69 	// connected in the first 10 seconds.
       
    70 	iCloseTimer = CSendAsServerTimer::NewL();
       
    71 	iCloseTimer->After(KSendAsServerInitCloseTime);
       
    72 	
       
    73 	iActiveContainer = CSendAsActiveContainer::NewL(*this);
       
    74 	
       
    75 	StartL(KSendAsServerName);
       
    76 	}
       
    77 
       
    78 CSendAsServer::CSendAsServer()
       
    79 : CServer2(CActive::EPriorityStandard)
       
    80 	{
       
    81 	}
       
    82 
       
    83 CSendAsServer::~CSendAsServer()
       
    84 	{
       
    85 	delete iCloseTimer;
       
    86 	delete iContainerIndex;
       
    87 	delete iActiveContainer;
       
    88 	delete iMtmManager;	
       
    89 	delete iMsvSession;
       
    90 
       
    91 	REComSession::FinalClose();
       
    92 	}
       
    93 	
       
    94 /** Create a new session.
       
    95 
       
    96 Called inside the NewSessionL callback.  This creates a new session
       
    97 using the factory function.  The new session will call back into the server to
       
    98 request an object container from the index during the operation of this factory function.
       
    99 */
       
   100 CSession2* CSendAsServer::DoNewSessionL(const TVersion& aVersion, const RMessage2& /*aMsg*/)
       
   101 	{
       
   102 	// stop the delayed startup shutdown mechanism
       
   103 	iCloseTimer->Cancel();
       
   104 	
       
   105 	CSendAsSession* session = CSendAsSession::NewL(aVersion, *this);
       
   106 	return session;
       
   107 	}
       
   108 	
       
   109 /** Create a new session.
       
   110 
       
   111 The callback called by the server framework when a client calls Connect on an RSession-derived
       
   112 object.
       
   113 In the SendAs Server, a server-side CSendAsSession represents an RSendAs client-side object.
       
   114 */
       
   115 CSession2* CSendAsServer::NewSessionL(const TVersion& aVersion, const RMessage2& aMsg) const
       
   116 	{
       
   117 	return ((CSendAsServer*)this)->DoNewSessionL(aVersion, aMsg);
       
   118 	}
       
   119 
       
   120 /** Generate a new object container for the session.
       
   121 
       
   122 (Callback from session creation factory function).
       
   123 Server remembers how many sessions are open.
       
   124 */
       
   125 CObjectCon* CSendAsServer::NewContainerL()
       
   126 	{
       
   127 	CObjectCon* con = iContainerIndex->CreateL();
       
   128 	++iOpenSessions;
       
   129 	return con;
       
   130 	}
       
   131 
       
   132 /** Indication of session closing down.
       
   133 
       
   134 Called from the session destructor to allow the server to dereference the
       
   135 object container for that session.
       
   136 */
       
   137 void CSendAsServer::SessionClosed(CObjectCon* aSessionContainer)
       
   138 	{
       
   139 	if( aSessionContainer != NULL)
       
   140 		{
       
   141 		iContainerIndex->Remove(aSessionContainer);
       
   142 		--iOpenSessions;
       
   143 		if( iOpenSessions == 0 )
       
   144 			{
       
   145 			if ( iActiveContainer->IsEmpty() )
       
   146 				{
       
   147 				iCloseTimer->After(KSendAsServerCloseTime);
       
   148 				}
       
   149 			else
       
   150 				{
       
   151 				// ensure no orphaned entries in background task container
       
   152 				iActiveContainer->PurgeInactive();
       
   153 				}
       
   154 			}
       
   155 		}
       
   156 	}
       
   157 
       
   158 CSendAsActiveContainer& CSendAsServer::ActiveContainer()
       
   159 	{
       
   160 	return *iActiveContainer;
       
   161 	}
       
   162 
       
   163 void CSendAsServer::ContainerEmpty()
       
   164 	{
       
   165 	// if no open sessions, start server shutdown timer
       
   166 	if( iOpenSessions == 0 )
       
   167 		{
       
   168 		iCloseTimer->After(KSendAsServerCloseTime);
       
   169 		}
       
   170 	}
       
   171 
       
   172 void CSendAsServer::ReadResourceFileL()
       
   173 	{
       
   174 	RFs fs;
       
   175 	User::LeaveIfError(fs.Connect());
       
   176 	CleanupClosePushL(fs);
       
   177 		
       
   178 	RResourceFile file;
       
   179     file.OpenL(fs, KSendAsServerResourceFile);
       
   180     
       
   181     CleanupClosePushL(file);
       
   182 
       
   183 	// Read the resource
       
   184 	HBufC8* resBuf = file.AllocReadLC(1);
       
   185 
       
   186 	// interpret the resource buffer
       
   187 	TResourceReader reader;
       
   188 	reader.SetBuffer(resBuf);
       
   189 	
       
   190 	// Read Edit Tools plugin UID and SendAs Confirm Notifier UID
       
   191 	TInt resVersion     = reader.ReadInt32();
       
   192 	iEditUtilsPluginUid = TUid::Uid(reader.ReadInt32());
       
   193 	iNotifierUid        = TUid::Uid(reader.ReadInt32());
       
   194 	
       
   195 	if (resVersion != KResVersion || iEditUtilsPluginUid == KNullUid || iNotifierUid == KNullUid)
       
   196 		{
       
   197 		User::Leave(KErrCorrupt);
       
   198 		}
       
   199 
       
   200 	CleanupStack::PopAndDestroy(3, &fs);	// resBuf, file, fs
       
   201 	}
       
   202 
       
   203 const TUid& CSendAsServer::NotifierUid() const
       
   204 	{
       
   205 	return iNotifierUid;
       
   206 	}
       
   207 
       
   208 const TUid& CSendAsServer::EditUtilsPluginUid() const
       
   209 	{
       
   210 	return iEditUtilsPluginUid;
       
   211 	}
       
   212 
       
   213 CMsvSession& CSendAsServer::GetMsvSessionL()
       
   214 	{ 
       
   215 	// if session has become lazy - create new session
       
   216 	if (iMsvSession == NULL)
       
   217 		{
       
   218 		iMsvSession = CMsvSession::OpenSyncL(*this);
       
   219 		}
       
   220 	return *iMsvSession; 
       
   221 	}
       
   222 
       
   223 CSendAsMtmManager* CSendAsServer::GetMtmManager()
       
   224 	{ 
       
   225 	return iMtmManager;
       
   226 	}
       
   227 
       
   228 /** Message Server Session Observer Callback.
       
   229 
       
   230 Used to keep track of the status of the message server.
       
   231 
       
   232 @param	aEvent
       
   233 The message server event to be handled.
       
   234 */
       
   235 void CSendAsServer::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
       
   236 	{
       
   237 	switch(aEvent)
       
   238 		{
       
   239 	case EMsvServerTerminated:
       
   240 	case EMsvCloseSession:
       
   241 		// close session (be lazy)
       
   242 		delete iMsvSession;
       
   243 		iMsvSession = NULL;
       
   244 		break;
       
   245 	case EMsvMtmGroupDeInstalled:
       
   246 	case EMsvMtmGroupInstalled:
       
   247 		// handle mtm installation/uninstallation 
       
   248 		HandleMtmChangeL(aEvent);
       
   249 		break;
       
   250 	case EMsvCorruptedIndexRebuilding:
       
   251 	case EMsvCorruptedIndexRebuilt:
       
   252 		// ignore
       
   253 	case EMsvEntriesChanged:
       
   254 	case EMsvEntriesCreated:
       
   255 	case EMsvEntriesDeleted:
       
   256 	case EMsvEntriesMoved:
       
   257 		// don't care
       
   258 	case EMsvGeneralError:
       
   259 		// not used after v5
       
   260 	case EMsvMediaAvailable:
       
   261 	case EMsvMediaChanged:
       
   262 	case EMsvMediaIncorrect:
       
   263 	case EMsvMediaUnavailable:
       
   264 		// not to worry - appropriate errors will filter back to client
       
   265 	case EMsvServerReady:
       
   266 	case EMsvServerFailedToStart:
       
   267 		// shouldn't happen since session is synchronously opened
       
   268 		break;	
       
   269 	default:
       
   270 		break;
       
   271 		}
       
   272 	}
       
   273 
       
   274 void CSendAsServer::HandleMtmChangeL(TMsvSessionEvent& aEvent)
       
   275 	{
       
   276 	// update the MTM manager
       
   277 	iMtmManager->RefreshMtmUidArrayL();
       
   278 	
       
   279 	// call each session's MTM Change handling method if a MTM has been de-installed
       
   280 	if (aEvent == EMsvMtmGroupDeInstalled)
       
   281 		{
       
   282 		iSessionIter.SetToFirst();
       
   283 		CSendAsSession* ses = (CSendAsSession*)&(*iSessionIter++);
       
   284 		while (ses!=NULL)
       
   285 			{
       
   286 			ses->HandleMtmChange();
       
   287 			ses = (CSendAsSession*)&(*(iSessionIter++));
       
   288 			}
       
   289 		}
       
   290 	}