phonebookengines/contactsmodel/cntsrv/src/CCntItemMsgHandler.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 // Copyright (c) 2007-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "CCntMsgHandler.h"
       
    22 #include "CCntMsgHandlerFptr.h"
       
    23 #include "CCntItemMsgHandler.h"
       
    24 
       
    25 #include "CCntIpcCodes.h"
       
    26 #include "CCntRequest.h"
       
    27 #include "CCntDbManager.h"
       
    28 #include "CCntStateMachine.h"
       
    29 #include "CCntDbManagerController.h"
       
    30 #include "CCntBackupRestoreAgent.h"
       
    31 #include "CCntPackager.h"
       
    32 #include "CntSpeedDials.h"
       
    33 
       
    34 const TInt KCntItemIpcCodes[] =
       
    35 	{
       
    36 	ECntItemCreate,
       
    37 	ECntItemUpdate,
       
    38 	ECntItemDelete,
       
    39 	ECntItemRead,
       
    40 	ECntItemCommit,
       
    41 	ECntItemOpen,
       
    42 	ECntItemClose,
       
    43 	ECntConnectionId,
       
    44 	ECntGetCurrentItem,
       
    45 	ECntRemoveCurrentItem,
       
    46 	ECntSetCurrentItem,
       
    47 	ECntGetCurrentDb,
       
    48 	ECntSetCurrentDb,
       
    49 	ECntGetSpeedDialContactIdAndPhoneNumber,
       
    50 	ECntSetSpeedDialIdForPosition,
       
    51 	ECntSetOwnCard,
       
    52 	ECntGetOwnCard,
       
    53 	ECntGetCollection,
       
    54 	ECntSetSortPrefs,
       
    55 	ECntGetSortPrefs,
       
    56 	ECntSetDbViewContactType,
       
    57 	ECntGetDbViewContactType,
       
    58 	ECntDbContactCount,
       
    59 	ECntFindAsync,
       
    60 	ECntFindAsyncInit,
       
    61 	ECntFindAsyncTextDefInit,
       
    62 	ECntFind,
       
    63 	ECntFilterDatabase,
       
    64 	ECntSetAsyncActivity,
       
    65 	ECntResourceCount,
       
    66 	ECntSetHeapFailure,
       
    67 	ECntSeekContactInCollection
       
    68 	};
       
    69 
       
    70 CCntItemMsgHandler* CCntItemMsgHandler::NewLC(CCntSession& aSession)
       
    71 	{	
       
    72 	CCntItemMsgHandler* CntItemMsgHandler = new (ELeave) CCntItemMsgHandler(aSession);
       
    73 	CleanupStack::PushL(CntItemMsgHandler);
       
    74 	return CntItemMsgHandler;
       
    75 	}	
       
    76 
       
    77 CCntItemMsgHandler::CCntItemMsgHandler(CCntSession& aSession)
       
    78 :CCntMsgHandler(aSession)
       
    79 	{	
       
    80 	}
       
    81 	
       
    82 CCntItemMsgHandler::~CCntItemMsgHandler()
       
    83 	{
       
    84 	}
       
    85 	
       
    86 /**
       
    87 Delegates the incoming op code to a message handling method.
       
    88 
       
    89 First checks if this class services the op code, it then uses the lookup table and finds 
       
    90 function pointer(to message handling method) mapped to the incoming message function (op code)
       
    91 and finally delegates the message to handling method.
       
    92 
       
    93 It returns KErrNotFound if op code not handled.
       
    94 */
       
    95 TInt CCntItemMsgHandler::HandleMessageL(const RMessage2& aMessage)
       
    96 	{	
       
    97 	MsgHandlerFptr func_ptr = LookupHandlerMethodL(aMessage.Function(), KCntItemIpcCodes, sizeof(KCntItemIpcCodes)/sizeof(TInt));
       
    98 	
       
    99 	if(func_ptr)
       
   100 		{
       
   101 		ItemMsgHandlerFptr mem_func_ptr = static_cast<ItemMsgHandlerFptr>(func_ptr);
       
   102 		(this->*mem_func_ptr)(aMessage);
       
   103 		return (KErrNone);
       
   104 		}
       
   105 	
       
   106 	return (KErrNotFound);
       
   107 	}
       
   108 	
       
   109 /**
       
   110 Message handling methods.
       
   111 
       
   112 N.B.: Some operations use aMessage.Complete() to return the a contact ID.  This
       
   113 is not convention but saves on IPC overhead.  Only one parameter is returned as
       
   114 opposed to two (error code and contact ID).
       
   115 
       
   116 @param aMessage The message typically containing the Contact Item.
       
   117 */
       
   118 void CCntItemMsgHandler::ItemCreateL(const RMessage2& aMessage)
       
   119 	{
       
   120 	CheckForManagerL();
       
   121 	CReqCreateCnt* request = CReqCreateCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
       
   122 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   123 	
       
   124 	// ProcessRequestL received ownership of the request, the request only need
       
   125 	// to be popped from CleanupStack.		
       
   126 	CleanupStack::Pop(request);
       
   127 	}
       
   128 	
       
   129 void CCntItemMsgHandler::ItemUpdateL(const RMessage2& aMessage)
       
   130 	{
       
   131 	CheckForManagerL();
       
   132 	CReqUpdateCnt* request = CReqUpdateCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
       
   133 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   134 	
       
   135 	// ProcessRequestL received ownership of the request, the request only need
       
   136 	// to be popped from CleanupStack.		
       
   137 	CleanupStack::Pop(request);
       
   138 	}
       
   139 	
       
   140 void CCntItemMsgHandler::ItemDeleteL(const RMessage2& aMessage)
       
   141 	{
       
   142 	CheckForManagerL();
       
   143 	CReqDeleteCnt* request = CReqDeleteCnt::NewLC(iSessionId, aMessage, iTimeOut);
       
   144 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   145 	
       
   146 	// ProcessRequestL received ownership of the request, the request only need
       
   147 	// to be popped from CleanupStack.		
       
   148 	CleanupStack::Pop(request);
       
   149 	}
       
   150 	
       
   151 void CCntItemMsgHandler::ItemReadL(const RMessage2& aMessage)
       
   152 	{
       
   153 	CheckForManagerL();
       
   154 	CReqReadCnt* request = CReqReadCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager, iView->ItemDef());
       
   155 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   156 	
       
   157 	// ProcessRequestL received ownership of the request, the request only need
       
   158 	// to be popped from CleanupStack.		
       
   159 	CleanupStack::Pop(request);
       
   160 	}
       
   161 	
       
   162 void CCntItemMsgHandler::ItemCommitL(const RMessage2& aMessage)
       
   163 	{
       
   164 	CheckForManagerL();
       
   165 	CReqCommitCnt* request = CReqCommitCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager);
       
   166 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   167 	
       
   168 	// ProcessRequestL received ownership of the request, the request only need
       
   169 	// to be popped from CleanupStack.		
       
   170 	CleanupStack::Pop(request);
       
   171 	}
       
   172 	
       
   173 void CCntItemMsgHandler::ItemOpenL(const RMessage2& aMessage)
       
   174 	{
       
   175 	CheckForManagerL();
       
   176 	CReqOpenCnt* request = CReqOpenCnt::NewLC(iSessionId, aMessage, iTimeOut, iPackager, iView->ItemDef());
       
   177 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   178 	
       
   179 	// ProcessRequestL received ownership of the request, the request only need
       
   180 	// to be popped from CleanupStack.		
       
   181 	CleanupStack::Pop(request);
       
   182 	}
       
   183 	
       
   184 void CCntItemMsgHandler::ItemCloseL(const RMessage2& aMessage)
       
   185 	{
       
   186 	CheckForManagerL();
       
   187 	CReqCloseCnt* request = CReqCloseCnt::NewLC(iSessionId, aMessage, iTimeOut);
       
   188 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   189 	
       
   190 	// ProcessRequestL received ownership of the request, the request only need
       
   191 	// to be popped from CleanupStack.		
       
   192 	CleanupStack::Pop(request);
       
   193 	}
       
   194 
       
   195 void CCntItemMsgHandler::ConnectionId(const RMessage2& aMessage)
       
   196 	{
       
   197 	// Complete the request with the session ID.
       
   198 	aMessage.Complete(iSessionId);
       
   199 	}
       
   200 	
       
   201 void CCntItemMsgHandler::GetCurrentItemL(const RMessage2& aMessage)
       
   202 	{
       
   203 	CheckForManagerL();			
       
   204 	TContactItemId currentItem(iManager->CurrentItem());
       
   205  	// Complete the request with the contact ID of the current item.
       
   206  	aMessage.Complete(currentItem);
       
   207 	}
       
   208 	
       
   209 void CCntItemMsgHandler::RemoveCurrentItemL(const RMessage2& aMessage)
       
   210 	{
       
   211 	CheckForManagerL();
       
   212 	iManager->RemoveCurrentItemL(iSessionId);
       
   213 	aMessage.Complete(KErrNone);
       
   214 	}
       
   215 	
       
   216 void CCntItemMsgHandler::SetCurrentItemL(const RMessage2& aMessage)
       
   217 	{
       
   218 	CheckForManagerL();
       
   219 	TContactItemId newCurrentItem = aMessage.Int0();
       
   220 	iManager->SetCurrentItemL(newCurrentItem, iSessionId);
       
   221 	aMessage.Complete(KErrNone);
       
   222 	}
       
   223 
       
   224 void CCntItemMsgHandler::GetCurrentDb(const RMessage2& aMessage)
       
   225 	{
       
   226 	WriteL(aMessage, KSlot0, Server().Controller().CurrentDb());
       
   227 	aMessage.Complete(KErrNone);
       
   228 	}
       
   229 	
       
   230 void CCntItemMsgHandler::SetCurrentDbL(const RMessage2& aMessage)
       
   231 	{
       
   232 	CheckForManagerL();
       
   233 	// Slot 0 in aMessage contains the new current database.
       
   234 	TFileName newCurrentDb;
       
   235 	ReadL(aMessage, KSlot0, newCurrentDb);
       
   236 	// Is this database already open for this session? We make it a
       
   237 	// pre-condition that you cannot set the current database to be one
       
   238 	// that isn't already open by this client.  This prevents errors
       
   239 	// whereby a client updates the current database, but then fails to
       
   240 	// open it.
       
   241 	if	(newCurrentDb.CompareF(iManager->CntFile()) == 0)
       
   242 		{
       
   243 		Server().Controller().SetCurrentDbL(newCurrentDb, iSessionId);				
       
   244 		}
       
   245 	aMessage.Complete(KErrNone);
       
   246 	}
       
   247 	
       
   248 void CCntItemMsgHandler::GetSpeedDialContactIdAndPhoneNumberL(const RMessage2& aMessage)
       
   249 	{
       
   250 	CheckForManagerL();
       
   251 	const TInt speedDialIndex = aMessage.Int0();		
       
   252 	TSpeedDialPhoneNumber phoneNumber;
       
   253 	TContactItemId contactId;
       
   254 	iManager->GetSpeedDialContactIdAndPhoneNumberL(speedDialIndex, phoneNumber, contactId);
       
   255 	aMessage.WriteL(KSlot1, phoneNumber);
       
   256 	aMessage.Complete(contactId);
       
   257 	}
       
   258 	
       
   259 void CCntItemMsgHandler::SetSpeedDialIdForPositionL(const RMessage2& aMessage)
       
   260 	{
       
   261 	CheckForManagerL();
       
   262 	// fetch the old contacts ID
       
   263 	const CCntServerSpeedDialTable& table = iManager->IniFileManager().SpeedDialManager().TableL(iManager->CntFile());
       
   264 	CReqSetSpeedDial* request = CReqSetSpeedDial::NewLC(iSessionId, 
       
   265 														aMessage, 
       
   266 														iTimeOut,
       
   267 														iView->ItemDef(),
       
   268 														iManager->IniFileManager().SpeedDialManager(),
       
   269 														table,
       
   270 														*iManager);
       
   271 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   272 	
       
   273 	// ProcessRequestL received ownership of the request, the request only need
       
   274 	// to be popped from CleanupStack.		
       
   275 	CleanupStack::Pop(request);
       
   276 	}
       
   277 	
       
   278 void CCntItemMsgHandler::SetOwnCardL(const RMessage2& aMessage)
       
   279 	{
       
   280 	CheckForManagerL();
       
   281 	CReqSetOwnCard* request = CReqSetOwnCard::NewLC(iSessionId, 
       
   282 													aMessage, 
       
   283 													iTimeOut,
       
   284 													iPackager,
       
   285 													iView->ItemDef(),
       
   286 													*iManager);
       
   287 	iManager->StateMachineL().ProcessRequestL(request);  // ownership transferred
       
   288 	
       
   289 	// ProcessRequestL received ownership of the request, the request only need
       
   290 	// to be popped from CleanupStack.		
       
   291 	CleanupStack::Pop(request);
       
   292 	}
       
   293 	
       
   294 void CCntItemMsgHandler::GetOwnCardL(const RMessage2& aMessage)
       
   295 	{
       
   296 	CheckForManagerL();
       
   297 	aMessage.Complete(iManager->GetPersistenceLayer().ContactProperties().OwnCardIdL());
       
   298 	}
       
   299 	
       
   300 void CCntItemMsgHandler::GetCollectionL(const RMessage2& aMessage)
       
   301 	{
       
   302 	CheckForManagerL();
       
   303 	
       
   304 	// If backup or restore is in progress then database cannot be accessed.
       
   305 	CCntBackupRestoreAgent& burAgent = iManager->BackupRestoreAgent();
       
   306 	if(burAgent.BackupInProgress() || burAgent.RestoreInProgress())
       
   307 		{
       
   308 		User::Leave(KErrLocked);
       
   309 		}
       
   310 
       
   311 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   312 	MLplCollection::TLplViewType type = static_cast<MLplCollection::TLplViewType>(aMessage.Int1());
       
   313 	CContactIdArray* idArray = NULL;
       
   314 
       
   315 	switch(type)
       
   316 		{
       
   317 		case MLplCollection::EChangedSince :
       
   318 			{
       
   319 			TTime time(0);
       
   320 			TPckgBuf<TTime> buf(time);
       
   321 			aMessage.ReadL(2,buf);
       
   322 			time = buf();
       
   323 			idArray = collection.CollectionL(type,time,KNullDesC);
       
   324 			}
       
   325 			break;
       
   326 
       
   327 		case MLplCollection::EFindGuid :
       
   328 			{
       
   329 			TTime time(0);
       
   330 			TBuf<64> buf;
       
   331 			aMessage.ReadL(2,buf);
       
   332 			idArray = collection.CollectionL(type,time,buf);
       
   333 			}
       
   334 			break;
       
   335 
       
   336 		// Maps to RCntModel::MatchPhoneNumberL().
       
   337 		case MLplCollection::EMatchPhoneNos:
       
   338 			{
       
   339 			const TInt receivingBufLen = aMessage.GetDesLengthL(2);
       
   340 			HBufC* buf = HBufC::NewLC(receivingBufLen); // digits in the number
       
   341 			TPtr ptr(const_cast<TUint16*>(buf->Ptr()), receivingBufLen);
       
   342 			aMessage.ReadL(2, ptr);
       
   343 			idArray = collection.MatchPhoneNumberL(ptr, aMessage.Int3());
       
   344 			CleanupStack::PopAndDestroy(buf);
       
   345 			}
       
   346 			break;	
       
   347 
       
   348 		default :
       
   349 			{
       
   350 			idArray = collection.CollectionL(type);
       
   351 			}
       
   352 			break;
       
   353 		}
       
   354 	
       
   355 	CleanupStack::PushL(idArray);
       
   356 	TPtr8 ptr = iPackager.PackL(*idArray);
       
   357 	TInt length = ptr.Length();
       
   358 	
       
   359 	if(aMessage.GetDesMaxLength(0) >= length)
       
   360 		{
       
   361 		aMessage.WriteL(0,ptr); 
       
   362 		aMessage.Complete(KErrNone);
       
   363 		}
       
   364 	else
       
   365 		{
       
   366 		aMessage.Complete(length);
       
   367 		}
       
   368 	
       
   369 	CleanupStack::PopAndDestroy(idArray);
       
   370 	}
       
   371 	
       
   372 void CCntItemMsgHandler::SetSortPrefsL(const RMessage2& aMessage)
       
   373 	{
       
   374 	CheckForManagerL();
       
   375 	iPackager.SetBufferFromMessageL(aMessage);
       
   376 	CArrayFix<CContactDatabase::TSortPref>* prefs = iPackager.UnpackCArrayFixLC();
       
   377 	iManager->GetPersistenceLayer().ContactProperties().SetSortPrefsL(prefs);
       
   378 	CleanupStack::Pop(prefs);
       
   379 	aMessage.Complete(KErrNone);
       
   380 	}
       
   381 	
       
   382 void CCntItemMsgHandler::GetSortPrefsL(const RMessage2& aMessage)
       
   383 	{
       
   384 	CheckForManagerL();
       
   385 	const CArrayFix<CContactDatabase::TSortPref>& prefs = iManager->GetPersistenceLayer().ContactProperties().SortPrefsL();
       
   386 	TPtr8 ptr = iPackager.PackL(prefs);
       
   387 	TInt length = ptr.Length();
       
   388 	if(aMessage.GetDesMaxLength(0) >= length)
       
   389 		{
       
   390 		aMessage.WriteL(0,ptr); 
       
   391 		aMessage.Complete(KErrNone);
       
   392 		}
       
   393 	else
       
   394 		{
       
   395 		aMessage.Complete(length);
       
   396 		}
       
   397 	}
       
   398 	
       
   399 void CCntItemMsgHandler::SetDbViewContactTypeL(const RMessage2& aMessage)
       
   400 	{
       
   401 	CheckForManagerL();
       
   402 	iManager->GetPersistenceLayer().ContactProperties().SetDbViewContactType(TUid::Uid(aMessage.Int0()));
       
   403 	aMessage.Complete(KErrNone);
       
   404 	}
       
   405 	
       
   406 void CCntItemMsgHandler::GetDbViewContactTypeL(const RMessage2& aMessage)
       
   407 	{
       
   408 	CheckForManagerL();
       
   409 	TPckg<TUid> dbViewContactType(iManager->GetPersistenceLayer().ContactProperties().GetDbViewContactType());
       
   410 	aMessage.WriteL(0,dbViewContactType);
       
   411 	aMessage.Complete(KErrNone);
       
   412 	}
       
   413 	
       
   414 void CCntItemMsgHandler::DbContactCountL(const RMessage2& aMessage)
       
   415 	{
       
   416 	CheckForManagerL();
       
   417 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   418 	aMessage.Complete(collection.ContactCountL());
       
   419 	}
       
   420 	
       
   421 void CCntItemMsgHandler::FindAsyncL(const RMessage2& aMessage)
       
   422 	{
       
   423 	/* Maps to client side AsyncFindL().  Can and will be called iteratively by the 
       
   424 	client. One of the two intitialisations below (i.e. ECntFindAsyncInit or 
       
   425 	ECntFindAsyncTextDefInit will have been called prior to this call.
       
   426 	**/
       
   427 	
       
   428 	CheckForManagerL();
       
   429 			
       
   430 	TBool moreToGo(EFalse);
       
   431 	
       
   432 	// Call Persistence Layer to do the work.  moreToGo will be set to
       
   433 	// ETrue if client should call again.  CContactIdArray and TBool are
       
   434 	// return parameters to the client.
       
   435 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   436 	CContactIdArray* idArray = collection.FindAsyncL(moreToGo, iSessionId);
       
   437 	CleanupStack::PushL(idArray);
       
   438 	
       
   439 	TPckg<TBool> morePckg(moreToGo);
       
   440 	aMessage.WriteL(1,morePckg);
       
   441 	
       
   442 	TPtr8 ptr8 = iPackager.PackL(*idArray);
       
   443 	// Iterative calls rely on packager having large enough buffer.
       
   444 	// Client expands it to 4k before calling.
       
   445 	// Write back to client
       
   446 	aMessage.WriteL(0,ptr8);
       
   447 	
       
   448 	CleanupStack::PopAndDestroy(idArray); 
       
   449 	aMessage.Complete(KErrNone);
       
   450 	}
       
   451 	
       
   452 //
       
   453 void CCntItemMsgHandler::FindAsyncInitL(const RMessage2& aMessage)
       
   454 	{
       
   455 	/* Asynchronous find can use 2 types of initialisation which map to the 
       
   456 	two construction types in the old Contacts Model. One uses a CContactTextDef 
       
   457 	and CDesCArray and the other a CContactItemFieldDef and text descriptor. 
       
   458 	Once initialisation is complete the client-side CIdleFinder::doFindL() method 
       
   459 	calls AsyncFind().
       
   460 
       
   461 	Initialisation for asynchronous find using CContactItemFileldDef and TDesC.
       
   462 	**/
       
   463 	
       
   464 	CheckForManagerL();
       
   465 
       
   466 	// Read descriptor into HBuf.
       
   467 	HBufC* text = HBufC::NewLC(aMessage.GetDesLengthL(0));
       
   468 	TPtr ptr(text->Des());
       
   469 	aMessage.ReadL(0,ptr);
       
   470 
       
   471 	CContactItemFieldDef* fieldDef = NULL;
       
   472 	if(aMessage.GetDesLengthL(1) > 0)
       
   473 		{
       
   474 		// Use packager to unpack CContactItemFieldDef.
       
   475 		iPackager.SetBufferFromMessageL(aMessage,1);
       
   476 		fieldDef = static_cast<CContactItemFieldDef*> (iPackager.UnpackTUidArrayLC());
       
   477 		CleanupStack::Pop(fieldDef);
       
   478 		}
       
   479 	
       
   480 	// Persistence Layer does the actual initialisation and also takes
       
   481 	// ownership of fielDef.
       
   482 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   483 	collection.FindAsyncInitL(text->Des(),fieldDef);
       
   484 	
       
   485 	CleanupStack::PopAndDestroy(text);
       
   486 	aMessage.Complete(KErrNone);
       
   487 	}
       
   488 	
       
   489 void CCntItemMsgHandler::FindAsyncTextDefInitL(const RMessage2& aMessage)
       
   490 	{
       
   491 	/* Initialisation for asynchronous find using CContactTextDef and array of 
       
   492 	"find words" constructed on the client-side and required on the server-side 
       
   493 	for matching.
       
   494 	**/
       
   495 	
       
   496 	CheckForManagerL();
       
   497 
       
   498 	// CContactTextDef can be NULL in which case the client will have
       
   499 	// passed an empty descriptor.
       
   500 	CContactTextDef* textDef = NULL;
       
   501 	// Assuming that a KNullDesC parameter results in max length of 0.
       
   502 	if(aMessage.GetDesLengthL(1) > 0)
       
   503 		{
       
   504 		// Use packager to unpack CContactTextDef.
       
   505 		iPackager.SetBufferFromMessageL(aMessage,1);
       
   506 		textDef = iPackager.UnpackCntTextDefLC();
       
   507 		CleanupStack::Pop(textDef);
       
   508 		}
       
   509 
       
   510 	// Unpack the CDesCArray manually as the packager does not package
       
   511 	// both.			
       
   512 	CBufFlat* bufFlat = CBufFlat::NewL(1 << 8);
       
   513 	CleanupStack::PushL(bufFlat);
       
   514 	bufFlat->ExpandL(0,aMessage.GetDesLengthL(0));
       
   515 	TPtr8 ptr8(bufFlat->Ptr(0));
       
   516 	aMessage.ReadL(0,ptr8);
       
   517 	RBufReadStream readStream;
       
   518 	readStream.Open(*bufFlat);
       
   519 	TInt count = readStream.ReadInt32L();
       
   520 	CDesCArray* unpacked = new (ELeave) CDesCArrayFlat(8);
       
   521 	CleanupStack::PushL(unpacked);
       
   522 	for(TInt i=0;i<count;++i)
       
   523 		{
       
   524 		TBuf<256> buf;
       
   525 		TInt length = readStream.ReadInt32L();
       
   526 		readStream.ReadL(buf,length);
       
   527 		unpacked->AppendL(buf);
       
   528 		}
       
   529 	readStream.Close();
       
   530 	
       
   531 	// Persistence Layer does the actual initialisation and also takes
       
   532 	// ownership of textDef.
       
   533 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   534 	collection.FindAsyncTextDefInitL(*unpacked,textDef);
       
   535 	
       
   536 	CleanupStack::PopAndDestroy(unpacked);
       
   537 	CleanupStack::PopAndDestroy(bufFlat);
       
   538 	aMessage.Complete(KErrNone);
       
   539 	}
       
   540 	
       
   541 void CCntItemMsgHandler::SeekContactL(const RMessage2& aMessage)
       
   542 	{
       
   543 	CheckForManagerL();
       
   544 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   545 	
       
   546 	TContactItemId actualId;
       
   547 	TUid contactType;
       
   548 	TBool deleted(EFalse);
       
   549 	// SeekContactL returns the Deleted Flag, the Contact ID and the
       
   550 	// contact type.
       
   551 	TBool seekRet = collection.SeekContactL(aMessage.Int0(),actualId,contactType,deleted);
       
   552 	
       
   553 	if(seekRet)
       
   554 		{
       
   555 		TPckg<TInt> idPckg(actualId);
       
   556 		aMessage.WriteL(1,idPckg);
       
   557 		TPckg<TUid> typePckg(contactType);
       
   558 		aMessage.WriteL(2,typePckg);
       
   559 		TPckg<TInt> deletePckg(deleted);
       
   560 		aMessage.WriteL(3,deletePckg);				
       
   561 		}
       
   562 		
       
   563 	aMessage.Complete(seekRet);	
       
   564 	}
       
   565 	
       
   566 void CCntItemMsgHandler::FindL(const RMessage2& aMessage)
       
   567 	{
       
   568 	// Maps to RCntModel::FindL() method.
       
   569 	
       
   570 	CheckForManagerL();
       
   571 						
       
   572 	// CContactItemFieldDef can be NULL in which case the client will
       
   573 	// have passed an empty descriptor.
       
   574 	CContactItemFieldDef* fieldDef = NULL;
       
   575 	// Assuming that a KNullDesC parameter results in max length of 0.
       
   576 	if(aMessage.GetDesLengthL(1) != 0)
       
   577 		{
       
   578 		// Slot 1 contains a serialized CArrayFixFlat<TUid>.  Since
       
   579 		// CContactItemFieldDef derives from it we can use the packager
       
   580 		// to unpack it.
       
   581 		iPackager.SetBufferFromMessageL(aMessage,1);
       
   582 		fieldDef = static_cast<CContactItemFieldDef*> (iPackager.UnpackTUidArrayLC());
       
   583 		}
       
   584 	
       
   585 	// Get the search text from slot 2
       
   586 	HBufC* text = HBufC::NewLC(aMessage.GetDesLengthL(2));
       
   587 	TPtr ptr(text->Des());
       
   588 	aMessage.ReadL(2,ptr);
       
   589 
       
   590 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   591 	collection.Reset();
       
   592 	
       
   593 	// Call the Persistence Layer to perform the find.
       
   594 	CContactIdArray* idArray = collection.FindL(ptr,fieldDef, iSessionId);
       
   595 	CleanupStack::PopAndDestroy(text);
       
   596 
       
   597 	// Package the contact ID array for return.
       
   598 	CleanupStack::PushL(idArray);
       
   599 	TPtr8 ptr8 = iPackager.PackL(*idArray);
       
   600 	TInt length = ptr8.Length();
       
   601 	
       
   602 	// Check the descriptor from the client is large enough.
       
   603 	if(aMessage.GetDesMaxLength(0) >= length)
       
   604 		{
       
   605 		// Write back to client.
       
   606 		aMessage.WriteL(0,ptr8); 
       
   607 		aMessage.Complete(KErrNone);
       
   608 		}
       
   609 	else
       
   610 		{
       
   611 		// Return required size of buffer to the client.
       
   612 		aMessage.Complete(length);
       
   613 		}
       
   614 	CleanupStack::PopAndDestroy(idArray);
       
   615 	if(fieldDef)
       
   616 		{
       
   617 		CleanupStack::PopAndDestroy(fieldDef);
       
   618 		}	
       
   619 	}
       
   620 	
       
   621 void CCntItemMsgHandler::FilterDatabaseL(const RMessage2& aMessage)
       
   622 	{
       
   623 	CheckForManagerL();
       
   624 	iPackager.SetBufferFromMessageL(aMessage);
       
   625 	CCntFilter* filter = iPackager.UnpackCntFilterLC();
       
   626 	MLplCollection& collection = iManager->GetPersistenceLayer().FactoryL().GetCollectorL();
       
   627 	CContactIdArray* idArray = collection.FilterDatabaseL(*filter);
       
   628 	CleanupStack::PopAndDestroy(filter);
       
   629 	CleanupStack::PushL(idArray);
       
   630 	TPtr8 ptr8 = iPackager.PackL(*idArray);
       
   631 	TInt length = ptr8.Length();
       
   632 	// Check the descriptor from the client is large enough.
       
   633 	if(aMessage.GetDesMaxLength(0) >= length)
       
   634 		{
       
   635 		// Write back to client.
       
   636 		aMessage.WriteL(0,ptr8); 
       
   637 		aMessage.Complete(KErrNone);
       
   638 		}
       
   639 	else
       
   640 		{
       
   641 		// Return required size of buffer to the client.
       
   642 		aMessage.Complete(length);
       
   643 		}
       
   644 	CleanupStack::PopAndDestroy(idArray);
       
   645 	}
       
   646 	
       
   647 void CCntItemMsgHandler::SetAsyncActivityL(const RMessage2& aMessage)
       
   648 	{
       
   649 	CheckForManagerL();
       
   650 	TBool asyncActivity = TBool(aMessage.Int0());
       
   651 	// Create and then process appropriate request using state machine.
       
   652 	CCntRequest* request = NULL;
       
   653 	if (asyncActivity)
       
   654 		{
       
   655 		request = CReqAsyncActivity::NewLC(iSessionId, aMessage, iTimeOut);
       
   656 		}
       
   657 	else
       
   658 		{
       
   659 		request = CReqNoAsyncActivity::NewLC(iSessionId, aMessage, iTimeOut);
       
   660 		}
       
   661 	iManager->StateMachineL().ProcessRequestL(request); // ownership transferred
       
   662 	
       
   663 	// ProcessRequestL received ownership of the request, the request only need
       
   664 	// to be popped from CleanupStack.		
       
   665 	CleanupStack::Pop(request);
       
   666 	}
       
   667 	
       
   668 void CCntItemMsgHandler::ResourceCount(const RMessage2& aMessage)
       
   669 	{
       
   670 	#if defined(_DEBUG)
       
   671 	TInt totalAllocSize(0);
       
   672 	User::Heap().AllocSize(totalAllocSize);
       
   673 	RDebug::Print(_L("[CNTMODEL] Heap count: %d cells, total heap size: %d bytes"), User::Heap().Count(), User::Heap().Size());
       
   674 	RDebug::Print(_L("[CNTMODEL] cntsrv heap size: %d bytes"), totalAllocSize);
       
   675 	aMessage.Complete(User::Heap().Count());
       
   676 	#else
       
   677 	aMessage.Complete(KErrNone);
       
   678 	#endif
       
   679 	}
       
   680 	
       
   681 void CCntItemMsgHandler::SetHeapFailure(const RMessage2& aMessage)
       
   682 	{
       
   683 	#if defined(_DEBUG)
       
   684 	User::__DbgSetAllocFail(RHeap::EUser,(RHeap::TAllocFail)aMessage.Int0(),aMessage.Int1());
       
   685 	#endif
       
   686 	aMessage.Complete(KErrNone);
       
   687 	}
       
   688